Using kotlin to develop Android application (13) – list control recyclerview

Time:2020-12-1

List control recyclerview

The recyclerview control is a more advanced, flexible version of listview.

A simple case

Add recyclerview to your layout
Open the application module.

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Get control in activity

    dataset = MutableList( DATASET_COUNT, { i -> "Element # $i" })
    recyclerViewAdapter = CustomRecyclerViewAdapter(dataset)
    layoutManager = LinearLayoutManager(this)
    recyclerView = findViewById(R.id.recyclerView)
    with(recyclerView) {
        setHasFixedSize(true)
        layoutManager
        adapter = recyclerViewAdapter
        itemAnimator = DefaultItemAnimator()
    }

custom adapter

    class CustomRecyclerViewAdapter(private val dataSet: MutableList<String>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
        private var size = 0;
        class NoramalViewHolder(v: View) : RecyclerView.ViewHolder(v) {
            val textView: TextView
            init {
              v.setOnClickListener { Log.d(TAG, "Element $adapterPosition clicked.") }
              textView = v.findViewById(android.R.id.text1)
            }
        }

        override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
            val v = LayoutInflater.from(viewGroup.context).inflate(android.R.layout.simple_list_item_1, viewGroup, false)
            return NoramalViewHolder(v)
        }

        // Replace the contents of a view (invoked by the layout manager)
        override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
            (viewHolder as NoramalViewHolder).textView.text = dataSet[position]
        }

        // Return the size of your dataset (invoked by the layout manager)
        override fun getItemCount() = size

        fun resetDataset() {
            dataSet.clear()
        }
        fun addDataSet( newDatas: List<String>?, m: Boolean ) {
            if (newDatas != null) {
                dataSet.addAll(newDatas)
            }
            size = dataSet.size
            more = m
            notifyDataSetChanged()
        }
    }

Use the swiperefreshlayout drop-down to update

Using swiperefreshlayout to wrap recyclerview in layout

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/swipe_refresh_layout">
    <androidx.recyclerview.widget.RecyclerView ...
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

Add a drop-down listener to your code

var swipeRefreshLayout: SwipeRefreshLayout
swipeRefreshLayout = findViewById<SwipeRefreshLayout>(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener { doWhenRefresh() }

Pull up loading

Modify the customrecyclerview adapter to monitor the scrolling of recyclerview to achieve pull-up loading

Create a new bottom to load more views

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center"
    android:padding="10dp">
    <ProgressBar
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"/>
    <TextView
     android:text="@string/load_more"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_marginStart="10dp"/>
</LinearLayout>

Add viewholder to the adapter and override getitemviewtype

class CustomRecyclerViewAdapter(private val dataSet: MutableList<String>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
     Private var more = false // variable, is there more data
     private var size = 0;

     class FootViewHolder(v: View) : RecyclerView.ViewHolder(v) {
     }

     override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
         if (viewType == normalType) {
            val v = LayoutInflater.from(viewGroup.context).inflate(android.R.layout.simple_list_item_1, viewGroup, false)
            return NoramalViewHolder(v)
         } else {
            val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.v_demo_load_more, viewGroup, false)
            return FootViewHolder(v)
         }
     }

     // Replace the contents of a view (invoked by the layout manager)
     override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
         if (position < size) {
            (viewHolder as NoramalViewHolder).textView.text = dataSet[position]
         }
     }

     // Return the size of your dataset (invoked by the layout manager)
     override fun getItemCount() = if (more) size + 1 else size
     Private val normaltype = 0 // first viewtype, normal item
     Private val foottype = 1 // the second viewtype, the bottom prompt view
     //The viewtype is returned according to the entry position to get different holders within the oncreateviewholder method
     override fun getItemViewType(position: Int): Int {
         return if (position < size) normalType else footType
     }
}

Add recyclerview listener

    addOnScrollListener(object : RecyclerView.OnScrollListener() {
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
             if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                if (lastVisibleItem + 1 == recyclerViewAdapter.getItemCount()) {
                    Handler().postDelayed({
                        doWhenLoad()
                    }, 1000)
               }
             }
         }

        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)
             if (recyclerView.layoutManager is LinearLayoutManager) {
                lastVisibleItem = (recyclerView.layoutManager as LinearLayoutManager).findLastVisibleItemPosition()
             } else if (recyclerView.layoutManager is GridLayoutManager) {
                lastVisibleItem = (recyclerView.layoutManager as GridLayoutManager).findLastVisibleItemPosition()
             }
        }
    })

Reference

  • Recyclerview official document
  • Official example of recyclerview
  • Examples of this article

Other articles

  • Developing Android application with kotlin (9) – bottom Navigation view
  • Using kotlin to develop Android application (10) – navigation of architecture components
  • Using kotlin to develop Android application (11) – viewpager of sliding view
  • Developing Android applications with kotlin (12) – dark theme

Recommended Today

Open, edit and save Microsoft office and Jinshan WPS document solutions in Google Chrome, Firefox and other browsers!

1、 Historical background In the mainstream browser version in 2015, Microsoft’s open source ActiveX control can be called directly to realize the online editing and review function of Microsoft office software. However, since 2015, major mainstream browsers have cancelled the npapi plug-in, resulting in a difficult problem in online editing office software. Although some commercial […]