Skip to content

Commit

Permalink
Feature: added the diff tool into adapter. Also, you can custom the d…
Browse files Browse the repository at this point in the history
…iff util into.
  • Loading branch information
pokk committed Aug 31, 2018
1 parent 1fa833a commit 2cd7bae
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 31 deletions.
4 changes: 2 additions & 2 deletions adaptiverecyclerview/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

implementation 'androidx.appcompat:appcompat:1.0.0-alpha3'
implementation 'androidx.recyclerview:recyclerview:1.0.0-alpha3'
implementation 'androidx.appcompat:appcompat:1.0.0-rc02'
implementation 'androidx.recyclerview:recyclerview:1.0.0-rc02'
}
repositories {
mavenCentral()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.devrapid.adaptiverecyclerview
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView

/**
Expand Down Expand Up @@ -35,41 +36,70 @@ abstract class AdaptiveAdapter<VT : ViewTypeFactory, M : IVisitable<VT>, VH : Re
notifyItemChanged(dataList.size)
}
}
open var diffUtil: AdaptiveDiffUtil<VT, M> = MultiDiffUtil()

protected abstract var typeFactory: VT
protected abstract var dataList: MutableList<M>

inner class MultiDiffUtil : AdaptiveDiffUtil<VT, M>() {
override var oldList = mutableListOf<M>()
override var newList = mutableListOf<M>()

override fun getOldListSize() = oldList.size

override fun getNewListSize() = newList.size

override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
oldList[oldItemPosition].hashCode() == newList[newItemPosition].hashCode()

override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) = true
}

//region Necessary override methods.
override fun getItemCount(): Int = this.dataList.size
override fun getItemCount(): Int = dataList.size

override fun getItemViewType(position: Int): Int = this.dataList[position].type(this.typeFactory)
override fun getItemViewType(position: Int): Int = dataList[position].type(typeFactory)

override fun onBindViewHolder(holder: VH, position: Int) =
(holder as AdaptiveViewHolder<VT, M>).initView(this.dataList[position], position, this)
(holder as AdaptiveViewHolder<VT, M>).initView(dataList[position], position, this)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
val itemView: View =
LayoutInflater.from(parent.context).inflate(this.typeFactory.getLayoutResource(viewType), parent, false)
LayoutInflater.from(parent.context).inflate(typeFactory.getLayoutResource(viewType), parent, false)

return this.typeFactory.createViewHolder(viewType, itemView) as VH
return typeFactory.createViewHolder(viewType, itemView) as VH
}
//endregion

fun appendList(list: MutableList<M>) {
open fun appendList(list: MutableList<M>) {
val startIndex = dataList.size

dataList.addAll(startIndex, list)
notifyItemRangeChanged(startIndex, list.size)
val newList = dataList.toMutableList().apply { addAll(startIndex, list) }
// notifyItemRangeChanged(startIndex, list.size)
updateList { newList }
}

fun dropList(startIndex: Int, endIndex: Int) {
open fun dropList(startIndex: Int, endIndex: Int) {
when {
startIndex < 0 || endIndex >= dataList.size -> throw IndexOutOfBoundsException("The range is over than list.")
startIndex > endIndex -> throw IndexOutOfBoundsException("startIndex index must be less than endIndex index.")
}
val newList = dataList.toMutableList()

repeat(endIndex - startIndex + 1) { dataList.removeAt(startIndex) }
notifyDataSetChanged()
repeat(endIndex - startIndex + 1) { newList.removeAt(startIndex) }
// notifyDataSetChanged()
updateList { newList }
}

fun clearList() = dropList(0, dataList.size - 1)
open fun clearList() = dropList(0, dataList.size - 1)

private fun updateList(getNewListBlock: () -> MutableList<M>) {
val newList = getNewListBlock()
val res = DiffUtil.calculateDiff(diffUtil.apply {
oldList = dataList
this.newList = newList
}, true)

dataList = newList
res.dispatchUpdatesTo(this)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.devrapid.adaptiverecyclerview

import androidx.recyclerview.widget.DiffUtil

abstract class AdaptiveDiffUtil<VT : ViewTypeFactory, M : IVisitable<VT>> : DiffUtil.Callback() {
abstract var oldList: MutableList<M>
abstract var newList: MutableList<M>
}
46 changes: 30 additions & 16 deletions sample/src/main/java/com/devrapid/example/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,42 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.devrapid.example.model.Animal
import com.devrapid.example.model.Person
import kotlinx.android.synthetic.main.activity_main.btn_add
import kotlinx.android.synthetic.main.activity_main.btn_minus
import kotlinx.android.synthetic.main.activity_main.recyclerView

class MainActivity: AppCompatActivity() {
class MainActivity : AppCompatActivity() {
var a = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val itemList: MutableList<IExpandVisitor> = mutableListOf(Person("Google"),
Person("Facebook", listOf(Animal("CEO"),
Animal("CTO"),
Animal("CDO"),
Animal("CAO"),
Animal("COO")), true),
Person("Apple", listOf(Animal("AEO"),
Animal("ATO"),
Animal("ADO")), true),
Person("Airbnb"),
Person("Jieyi"))
Person("Facebook", listOf(Animal("CEO"),
Animal("CTO"),
Animal("CDO"),
Animal("CAO"),
Animal("COO")), true),
Person("Apple", listOf(Animal("AEO"),
Animal("ATO"),
Animal("ADO")), true),
Person("Airbnb"),
Person("Jieyi"))

recyclerView.layoutManager =
androidx.recyclerview.widget.LinearLayoutManager(this,
androidx.recyclerview.widget.LinearLayoutManager.VERTICAL,
false)
recyclerView.adapter = ExpandAdapter(itemList)
val adapter = ExpandAdapter(itemList)
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recyclerView.adapter = adapter

btn_add.setOnClickListener {
adapter.appendList(listOf(Person("Google $a")) as MutableList<IExpandVisitor>)
a++
}
btn_minus.setOnClickListener {
adapter.dropList(1, 1)
}
btn_minus.setOnLongClickListener {
adapter.clearList()
true
}
}
}
16 changes: 16 additions & 0 deletions sample/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,20 @@
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp"/>

<Button
android:id="@+id/btn_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ADD"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

<Button
android:id="@+id/btn_minus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MINUS"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_add"/>
</androidx.constraintlayout.widget.ConstraintLayout>

0 comments on commit 2cd7bae

Please sign in to comment.