Create single adapter for any type of List Android

2019-08-20 10:14发布

问题:

I am trying to create Generic Adapter in Android.

I am succeeded in creating to the given level where I have to extend RecyclerBaseAdapter

import kotlinx.android.synthetic.main.activity_animal_list.*

class SubjectListActivity : AppCompatActivity() {

    var subjects = mutableListOf<SubjectBO>()
    val database = FirebaseDatabase.getInstance()
    lateinit var subjectAdapter: SubjectAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_animal_list)

        val myRef = database.getReference("rootNode/subRootNode/Subject")

        subjectAdapter = SubjectAdapter(
            R.layout.item_subject,
            subjects,
            { position, view ->
                val nextScreenIntent = Intent(this, LevelListActivity::class.java).apply {
                    putExtra("subjectKey", subjects.get(position).name)
                }
                startActivity(nextScreenIntent)
            })

        recycler_view.apply {
            layoutManager = LinearLayoutManager(this@SubjectListActivity)
            adapter = subjectAdapter
        }

        val subjectListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                dataSnapshot.children.mapNotNullTo(subjects) {
                    it.getValue<SubjectBO>(
                        SubjectBO::class.java
                    )
                }
                subjectAdapter.notifyDataSetChanged()
            }

            override fun onCancelled(databaseError: DatabaseError) {
                println("loadPost:onCancelled ${databaseError.toException()}")
            }
        }

        myRef.addValueEventListener(subjectListener)
    }
}

SubjectAdapter.kt

    class SubjectAdapter(
    layoutID: Int, itemList: List<SubjectBO>,
    onRecyclerItemClick: ((position: Int, view: View) -> Unit)?
) : RecyclerBaseAdapter<SubjectBO>(layoutID,itemList, onRecyclerItemClick) {
    override fun onBindViewHolder(holder: RecyclerBaseViewHolder, pos: Int) {
        holder.itemView.tv_subject.text = itemList.get(pos).name
    }
}

RecyclerBaseAdapter.kt

abstract class RecyclerBaseAdapter<BO>(private val layoutID: Int, val itemList: List<BO>,
                                       private val onRecyclerItemClick: ((position: Int, view: View) -> Unit)?
) : RecyclerView.Adapter<RecyclerBaseViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, position: Int): RecyclerBaseViewHolder {
        return RecyclerBaseViewHolder(parent, layoutID, onRecyclerItemClick)
    }
    override fun getItemCount(): Int {
        return itemList.size
    }
}

RecyclerBaseViewHolder

class RecyclerBaseViewHolder(parent: ViewGroup, layoutID: Int,onRecyclerItemClick: ((position:Int, view: View) -> Unit)?)
    : RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(layoutID, parent, false)){

    init {
        itemView.setOnClickListener {
                onRecyclerItemClick?.invoke(adapterPosition,it)
        }
    }
}

item_subject.xml

<?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"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="6dp"
        app:cardUseCompatPadding="true"
        app:cardElevation="4dp"
        app:cardCornerRadius="3dp">

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:orientation="horizontal">

        <TextView
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="10dp"
                android:textAlignment="center"
                android:textStyle="bold"
                android:text="Hello"
                android:textColor="@android:color/background_dark"
                android:textSize="20sp"
                android:id="@+id/tv_subject">

        </TextView>
    </LinearLayout>

</android.support.v7.widget.CardView>

Is it possible to create an adapter without need of AnimalNewAdapter. like below

animalAdapter = RecyclerBaseAdapter<Animal>(R.layout.item_animal,animalList, { position, view ->
            Toast.makeText(this@AnimalListActivity, "Clicked at :" + position, Toast.LENGTH_LONG).show()

            override fun onBindViewHolder(holder: RecyclerBaseViewHolder, pos: Int) {
                holder.itemView.tv_animal.text = itemList.get(pos).title
            }
        })

I want to remove this overhead to create a seperate adapter for each..