Skip to content

Commit

Permalink
Merge pull request #983 from mikepenz/develop
Browse files Browse the repository at this point in the history
dev -> main
  • Loading branch information
mikepenz committed Mar 4, 2021
2 parents 51742ea + 1b5d3b0 commit a31bfaf
Show file tree
Hide file tree
Showing 25 changed files with 133 additions and 55 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Expand Up @@ -28,6 +28,7 @@ proguard/

#IntelliJ files
*.iml
.idea/
.idea/*
!.idea/dictionaries

*.DS_STORE
*.DS_STORE
57 changes: 57 additions & 0 deletions .idea/dictionaries/benji.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion CONTRIBUTORS.md
@@ -1,4 +1,4 @@
FastAdapter contributors (sorted alphabeticaly)
FastAdapter contributors (sorted alphabetically)
============================================

* **[Fabian Terhorst](https://github.com/FabianTerhorst)**
Expand Down
12 changes: 6 additions & 6 deletions MIGRATION.md
Expand Up @@ -24,8 +24,8 @@ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, pa

#### v4.x.y

v4 is a huge release changing most of the codebase to Kotlin. This comes with many refactors, and as a result of that with many breaking API changes.
We put a lot of focus on type safety with this release, as such this release is a lot more strict and tries to prevent as many potential bad type mixups as possible.
v4 is a huge release changing most of the codebase to Kotlin. This comes with many refactorings, and as a result of that with many breaking API changes.
We put a lot of focus on type safety with this release, as such this release is a lot more strict and tries to prevent as many potential bad type mix-ups as possible.

* For compatibility, most existing static fields and functions remain static in Java. For newer functions, accessing from Java may require using the `Companion` class. For instance, `FastAdapter.example()` becomes `FastAdapter.Companion.example()`
* The `IItem` interface now requires a type specification. E.g. `IItem<RecyclerView.ViewHolder>`
Expand Down Expand Up @@ -57,7 +57,7 @@ If you have any issues during the migration, or any questions come up please ope
* Further details about migrating to androidX and a overview can be found on the official docs. https://developer.android.com/topic/libraries/support-library/refactor

#### v3.2.4
* Adjusted the `set(int position, Item item, int preItemCount)` to include the `preItemCount` to corretly notify the adapter about the changed element.
* Adjusted the `set(int position, Item item, int preItemCount)` to include the `preItemCount` to correctly notify the adapter about the changed element.

#### v3.2.3
* The `ActionModeHelper` requires a `FastAdapter` with the `SelectExtension` applied. This is done in current versions via `withSelectable(true)`. Make sure this is called before creating the `ActionModeHelper`.
Expand Down Expand Up @@ -156,17 +156,17 @@ public ViewHolder getViewHolder(View v) {

**SHORT OVERVIEW**
* If you have items implemented by using the interface you have to implement the new methods (**unbindView**)
* If you have expandable items make sure to adjust the Model type definitions as metioned below. Check out the `AbstractExpandableItem` to simplify this for you
* If you have expandable items make sure to adjust the Model type definitions as mentioned below. Check out the `AbstractExpandableItem` to simplify this for you
* If you use the `MaterialDrawer`, the `AboutLibraries` in your project, please make sure to update them so the changed interfaces do not cause conflicts

**DETAILED**
* New `unbindView` method was added to the `IItem` --> This method is called when the current item is no longer set and before the `ViewHolder` is used for the next item
* You should move your view resetting logic here, or for example glide image loading canceling
* `IExpandable` Model types changes
* it is now required to define the type which will be used for the subItems. This can be an implementation or `ISubItem`. We now require this, as we will keep the references between childs, and parents.
* it is now required to define the type which will be used for the subItems. This can be an implementation or `ISubItem`. We now require this, as we will keep the references between children, and parents.
* this allows more optimizations, and many additional usecases
* New `ISubItem` interface added
* items serving as subitems, have to implement this.
* items serving as subItems, have to implement this.
* New `AbstractExpandableItem` added, which combines `IExpandable` and `ISubItem` with an `AbstractItem` to simplify your life
* A new `SubItemUtil` was introduced which simplifies some use cases when working with expandable / collapsing lists

Expand Down
4 changes: 2 additions & 2 deletions README.md
@@ -1,7 +1,7 @@
# FastAdapter

The FastAdapter is here to simplify creating adapters for RecyclerViews. Don't worry about the adapter anymore. Just write the logic for how your view/item should look like, and you are done.
It's blazingly fast, minimizing the code you need to write, and is easy to extend.
It's blazing fast, minimizing the code you need to write, and is easy to extend.

-------

Expand Down Expand Up @@ -48,7 +48,7 @@ It's blazingly fast, minimizing the code you need to write, and is easy to exten

## Latest releases 🛠

- Kotlin | [v5.3.4](https://github.com/mikepenz/FastAdapter/tree/v5.3.4)
- Kotlin | [v5.3.5](https://github.com/mikepenz/FastAdapter/tree/v5.3.5)
- Java && AndroidX | [v3.3.1](https://github.com/mikepenz/FastAdapter/tree/v3.3.1)
- Java && AppCompat | [v3.2.9](https://github.com/mikepenz/FastAdapter/tree/v3.2.9)

Expand Down
Expand Up @@ -28,7 +28,7 @@ import java.util.*
import java.util.concurrent.atomic.AtomicLong

/**
* This sample showcases compatibility the awesome Sticky-Headers library by timehop
* This sample showcases compatibility with the awesome Sticky-Headers library by timehop
* https://github.com/timehop/sticky-headers-recyclerview
*/
class AdvancedSampleActivity : AppCompatActivity() {
Expand Down Expand Up @@ -82,7 +82,7 @@ class AdvancedSampleActivity : AppCompatActivity() {
if (item is IExpandable<*> && item.subItems.isNotEmpty()) {
true
} else {
//handle the longclick actions
//handle the long click actions
val actionMode = mActionModeHelper?.onLongClick(this@AdvancedSampleActivity, position)
if (actionMode != null) {
//we want color our CAB
Expand Down
Expand Up @@ -63,7 +63,7 @@ class DiffUtilActivity : AppCompatActivity() {

override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the adapter to the bundel
//add the values which need to be saved from the adapter to the bundle
outState = fastItemAdapter.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
Expand Down
Expand Up @@ -128,7 +128,7 @@ class ExpandableMultiselectDeleteSampleActivity : AppCompatActivity() {
.identifier = (i + 1).toLong()
//.withIsExpanded(true) don't use this in such a setup, use adapter.expand() to expand all items instead

//add subitems so we can showcase the collapsible functionality
//add subItems so we can showcase the collapsible functionality
val subItems = LinkedList<ISubItem<*>>()
for (ii in 1..5) {
val sampleItem = SimpleSubItem()
Expand Down Expand Up @@ -159,7 +159,7 @@ class ExpandableMultiselectDeleteSampleActivity : AppCompatActivity() {
val headerItem = item.parent
if (headerItem != null) {
val pos = fastItemAdapter.getAdapterPosition(headerItem)
// Important: notify the header directly, not via the notifyadapterItemChanged!
// Important: notify the header directly, not via the notifyAdapterItemChanged!
// we just want to update the view and we are sure, nothing else has to be done
fastItemAdapter.notifyItemChanged(pos)
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values/strings.xml
Expand Up @@ -45,6 +45,6 @@
<string name="sample_diff_util">Diff Util Sample</string>
<string name="sample_diff_util_descr">Diff Util, refresh list using DiffUtil</string>
<string name="open_source">Open Source</string>
<string name="search_title">Suche</string>
<string name="search_title">Search</string>
<string name="action_undo">UNDO</string>
</resources>
4 changes: 2 additions & 2 deletions build.gradle
Expand Up @@ -4,8 +4,8 @@ buildscript {

ext {
release = [
versionName: "5.3.4",
versionCode: 5034
versionName: "5.3.5",
versionCode: 5035
]

setup = [
Expand Down
Expand Up @@ -53,7 +53,7 @@ object AdapterUtil {
* Gets all items (including sub items) from the FastAdapter
*
* @param fastAdapter the FastAdapter
* @return a list of all items including the whole subItem hirachy
* @return a list of all items including the whole subItem hierarchy
*/
@JvmStatic fun <Item> getAllItems(fastAdapter: FastAdapter<Item>): List<Item> where Item : GenericItem, Item : IExpandable<*> {
val size = fastAdapter.itemCount
Expand Down
Expand Up @@ -165,7 +165,7 @@ object SubItemUtil {
}

/**
* Select or unselect all sub itmes underneath an expandable item
* Select or unselect all sub items underneath an expandable item
*
* @param adapter the adapter instance
* @param header the header who's children should be selected or deselected
Expand All @@ -176,7 +176,7 @@ object SubItemUtil {
}

/**
* Select or unselect all sub itmes underneath an expandable item
* Select or unselect all sub items underneath an expandable item
*
* @param adapter the adapter instance
* @param header the header who's children should be selected or deselected
Expand Down
Expand Up @@ -203,7 +203,7 @@ open class PagedItemListImpl<Model, Item : GenericItem>(
/**
* Returns the default placeholder interceptor
*
* Note if your PagedItemList should contain placeholder, you have to provide a logic what the adapter should show while in placeholding state
* Note if your PagedItemList should contain placeholder, you have to provide a logic what the adapter should show while in placeholder state
*/
internal fun <Item : GenericItem> getDefaultPlaceholderInterceptor(): (Int) -> Item {
return { throw RuntimeException("No item found at position") }
Expand Down
Expand Up @@ -51,7 +51,7 @@ abstract class EndlessRecyclerOnTopScrollListener : RecyclerView.OnScrollListene
super.onScrolled(recyclerView, dx, dy)
if (!::_layoutManager.isInitialized) {
this._layoutManager = recyclerView.layoutManager as LinearLayoutManager?
?: throw RuntimeException("A layoutmanager is required")
?: throw RuntimeException("A LayoutManager is required")
}

if (visibleThreshold == RecyclerView.NO_POSITION) {
Expand Down
@@ -1,5 +1,6 @@
package com.mikepenz.fastadapter.swipe

import android.annotation.SuppressLint
import android.graphics.Canvas
import android.graphics.Rect
import android.view.MotionEvent
Expand Down Expand Up @@ -29,10 +30,14 @@ class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs:
// Indicates whether the touchTransmitter has been set on the RecyclerView
private var touchTransmitterSet = false

// States of swiped items
// Key = item position
// Value = swiped direction (see {@link ItemTouchHelper})
private val swipedStates = HashMap<Int, Int>()
/**
* States of swiped items
* Key = item unique ID
* Value = swiped direction (see {@link androidx.recyclerView.widget.ItemTouchHelper})
*
* NB : As this class doesn't listen to the recyclerView, it may contain identifiers for old items that have been removed
*/
private val swipedStates = HashMap<Long, Int>()

// True if a swiping gesture is currently being done
var isSwiping = false
Expand Down Expand Up @@ -108,9 +113,10 @@ class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs:

override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position = viewHolder.adapterPosition
if (position != RecyclerView.NO_POSITION && (!swipedStates.containsKey(position) || swipedStates[position] != direction)) {
val id = viewHolder.itemId
if (position != RecyclerView.NO_POSITION && (!swipedStates.containsKey(id) || swipedStates[id] != direction)) {
itemSwipeCallback?.itemSwiped(position, direction)
swipedStates[position] = direction
swipedStates[id] = direction
isSwiping = false
}
}
Expand All @@ -127,10 +133,11 @@ class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs:
override fun getSwipeThreshold(viewHolder: RecyclerView.ViewHolder): Float {
// During the "unswipe" gesture, Android doesn't use the threshold value properly
// => Need to communicate an inverted value for swiped items
return if (swipedStates.containsKey(viewHolder.adapterPosition)) 1f - surfaceThreshold
return if (swipedStates.containsKey(viewHolder.itemId)) 1f - surfaceThreshold
else surfaceThreshold
}

@SuppressLint("ClickableViewAccessibility")
override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
val itemView = viewHolder.itemView

Expand All @@ -152,9 +159,9 @@ class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs:
val dXPercent = dX / recyclerView.width

// If unswiped, fire event and update swiped state
if (0f == dX && swipedStates.containsKey(position)) {
if (0f == dX && swipedStates.containsKey(viewHolder.itemId)) {
itemSwipeCallback?.itemUnswiped(viewHolder.adapterPosition)
swipedStates.remove(position)
swipedStates.remove(viewHolder.itemId)
}

// If the position is between "swiped" and "unswiped", then we're swiping
Expand All @@ -174,11 +181,17 @@ class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs:
* Android default touch event mechanisms don't transmit these events to the sublayer :
* any click on the exposed surface just swipes the item back to where it came
*/
@SuppressLint("ClickableViewAccessibility")
inner class RecyclerTouchTransmitter : View.OnTouchListener {

private var recyclerView: RecyclerView? = null

override fun onTouch(v: View?, event: MotionEvent): Boolean {
// No need for that when nothing is swiped or when swiping is in progress
if (isSwiping || null == v || v !is ViewGroup) return false

if (v is RecyclerView) recyclerView = v

// Get the first visible View under the clicked coordinates
val childView = v.getFirstVisibleViewByCoordinates(event.x, event.y)
// Transmit the ACTION_DOWN and ACTION_UP events to this View
Expand All @@ -198,6 +211,13 @@ class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs:
* Return the first visible non-ViewGroup View within the given ViewGroup, at the given coordinates
*/
private fun ViewGroup.getFirstVisibleViewByCoordinates(x: Float, y: Float): View? {

// If target viewHolder isn't swiped, don't bother going further
if (this.parent == recyclerView) {
val viewHolder = recyclerView?.getChildViewHolder(this)
if (!swipedStates.containsKey(viewHolder?.itemId)) return null
}

(childCount - 1 downTo 0)
.map { this.getChildAt(it) }
.forEach {
Expand Down
Expand Up @@ -88,7 +88,7 @@ class ActionModeHelper<Item : GenericItem> {

/**
* Implements the basic behavior of a CAB and multi select behavior,
* including logics if the clicked item is collapsible
* including logic if the clicked item is collapsible
*
* @param item the current item
* @return null if nothing was done, or a boolean to inform if the event was consumed
Expand All @@ -99,7 +99,7 @@ class ActionModeHelper<Item : GenericItem> {

/**
* Implements the basic behavior of a CAB and multi select behavior,
* including logics if the clicked item is collapsible
* including logic if the clicked item is collapsible
*
* @param act the current Activity
* @param item the current item
Expand Down
Expand Up @@ -31,9 +31,9 @@ class HeaderHelper<Item, HeaderItem : Item> {
}

/**
* Call this when your list order has changed or was updated, and you have to readd the headres
* Call this when your list order has changed or was updated, and you have to read the headers
*
* @param items the list which will get the headers added inbetween
* @param items the list which will get the headers added in-between
*/
fun apply(items: MutableList<Item>) {
//If the list is empty avoid sorting and adding headers.
Expand Down Expand Up @@ -69,7 +69,7 @@ class HeaderHelper<Item, HeaderItem : Item> {
interface GroupingFunction<Item, HeaderItem> {
/**
* @param currentItem the current item we check
* @param nextItem the item comming after the current item
* @param nextItem the item coming after the current item
* @param currentPosition the current position of the currentItem
* @return the HeaderItem we want to add after the currentItem
*/
Expand Down

0 comments on commit a31bfaf

Please sign in to comment.