Nous allons voir dans cette article comment utiliser un flexible adapter provenant de la librairie suivante :
https://github.com/davideas/FlexibleAdapter
Cette article montre la mise en place de ce Flexible Adapter n’utilisant qu’un seul type d’item. L’utilisation du flexible adapter n’a donc pas grand intérêt dans ce cas là. Un second, disponible ici, article vous montrera l’utilisation de plusieurs items au sein d’un seul et même adapter.
Voici une capture d’écran du résultat final
.
.
1 – Voici l’activité principale de l’application
class MainActivity : AppCompatActivity(), OrderFlexibleAdapter.OrderListener { private var orderList = ArrayList<Order>() private lateinit var orderListAdapter: OrderFlexibleAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) orderListAdapter = OrderFlexibleAdapter(orderList, this) laListe.apply { layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) adapter = orderListAdapter } val order1 = Order(1, "Titre 1", "Sous titre 1", false) val order2 = Order(2, "Titre 2", "Sous titre 2", false) // [...] val order20 = Order(20, "Titre 20", "Sous titre 20", false) orderList.add(order1) orderList.add(order2) // [...] orderList.add(order20) orderList.let { orderListAdapter.setData(it) } btnValidate.setOnClickListener { afficherLeResultat(orderList) } } private fun afficherLeResultat(orderList: ArrayList<Order>) { textResult.text = "Vous avez cliqué sur : " orderList.filter { it.validate == true }.apply { this.forEach { textResult.text = textResult.text.toString() + "${it.id} - " } } } override fun onOrderClicked(orderId: Int) { orderList.find { it.id == orderId }?.apply { this.validate = !this.validate } orderListAdapter.updateData() } }
.
Voici le layout associé à cette activité
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Exemple d'utilisation d'un Flexible Adapter " app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" android:id="@+id/textView"/> <android.support.v7.widget.RecyclerView android:id="@+id/laListe" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintTop_toBottomOf="@+id/textView" android:layout_marginTop="16dp" android:layout_marginBottom="8dp" app:layout_constraintBottom_toTopOf="@+id/btnValidate"/> <Button android:id="@+id/btnValidate" android:text="Valider" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp" android:layout_marginStart="8dp" android:layout_marginBottom="8dp" app:layout_constraintBottom_toTopOf="@+id/textResult"/> <TextView android:id="@+id/textResult" tools:text="Le résultat est ici " android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp" android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent"/> </android.support.constraint.ConstraintLayout>
.
.
2 – Création de la classe AbsFlexibleAdapter
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.viewholders.FlexibleViewHolder abstract class AbsFlexibleAdapter<FI : AbstractFlexibleItem<VH>, VH : FlexibleViewHolder>(items: List<FI>? = null) : FlexibleAdapter<FI>(items)
.
.
3 – Création de la classe AbsFlexibleViewHolder
import android.view.View import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.viewholders.FlexibleViewHolder open class AbsFlexibleViewHolder(view: View, adapter: FlexibleAdapter<out IFlexible<*>>, stickyHeader: Boolean = false) : FlexibleViewHolder(view, adapter, stickyHeader)
.
.
4 – Création de l’adapter OrderFlexibleAdapter
class OrderFlexibleAdapter(orderList: List<Order>, private val listener: OrderListener) : AbsFlexibleAdapter<AbstractFlexibleItem<AbsFlexibleViewHolder>, AbsFlexibleViewHolder>() { var orderList = orderList fun updateData() { setData(orderList) } fun setData(orderList: List<Order>) { val dataToDisplay = mutableListOf<AbstractFlexibleItem<AbsFlexibleViewHolder>>() orderList.forEach { order -> dataToDisplay.add(OrderFlexibleItem(order, listener)) } updateDataSet(dataToDisplay) } interface OrderListener { fun onOrderClicked(orderId: Int) } }
.
.
5 – Création de la classe OrderFlexibleItem
class OrderFlexibleItem(var order: Order, private val listener: OrderFlexibleAdapter.OrderListener) : AbstractFlexibleItem<AbsFlexibleViewHolder>(), FlexibleAdapter.OnItemClickListener { override fun bindViewHolder( adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>?, holder: AbsFlexibleViewHolder?, position: Int, payloads: MutableList<Any>? ) { (holder as ViewHolder).bind(order, listener) } override fun createViewHolder( view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>> ): AbsFlexibleViewHolder = ViewHolder(view, adapter) override fun getLayoutRes(): Int = R.layout.item_order override fun equals(other: Any?): Boolean = other is OrderFlexibleItem override fun onItemClick(view: View?, position: Int): Boolean { return false } class ViewHolder(view: View, adapter: FlexibleAdapter<out IFlexible<*>>) : AbsFlexibleViewHolder(view, adapter, false) { fun bind(order: Order, listener: OrderFlexibleAdapter.OrderListener) { contentView.setOnClickListener { order.id.let { orderId -> listener.onOrderClicked(orderId) } } contentView.title.text = order.title contentView.subTitle.text = order.subTitle contentView.checkBox.isChecked = order.validate } } }
.
Cette classe étant dépendante du fichier layout item_order.xml suivant
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="@dimen/order_view_item_height" android:layout_marginBottom="5dp" android:layout_marginLeft="@dimen/horizontal_padding" android:layout_marginRight="@dimen/horizontal_padding" android:layout_marginTop="5dp" android:background="@android:color/white" app:cardCornerRadius="4dp" app:cardElevation="4dp" > <android.support.constraint.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/title" tools:text="Commande AA-10" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp" android:layout_marginStart="8dp" android:layout_marginTop="6dp" app:layout_constraintTop_toTopOf="parent"/> <TextView android:id="@+id/subTitle" tools:text="0 sac" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp" android:layout_marginStart="8dp" android:layout_marginTop="4dp" app:layout_constraintTop_toBottomOf="@+id/title"/> <CheckBox android:id="@+id/checkBox" android:layout_width="wrap_content" android:layout_height="0dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:clickable="false" app:layout_constraintBottom_toBottomOf="parent"/> </android.support.constraint.ConstraintLayout> </android.support.v7.widget.CardView>
.
Voici la représentation graphique de ce layout :
.
.
6 – Il ne manque que l’objet utilisé par l’adapter. Création de la classe Order.kt
class Order(var id: Int, var title: String, var subTitle: String, var validate: Boolean)
.
.
7 – Il ne faut pas oublier d’importer la librairie du flexible adapter dans le fichier build de votre application
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'com.android.support:cardview-v7:28.0.0' implementation 'com.android.support:design:28.0.0' // Utilisation FlexibleAdapter - implementation "eu.davidea:flexible-adapter:5.0.5" implementation "eu.davidea:flexible-adapter-ui:1.0.0-b5" }