Android kotlin list adapter

How to write a custom adapter for my list view on Android using Kotlin?

This example demonstrates how to write a custom adapter for my list view on Android using Kotlin.

Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project.

Step 2 − Add the following code to res/layout/activity_main.xml.

Step 3 − Add the following code to src/MainActivity.kt

import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter import android.widget.ListView import android.widget.TextView import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() < lateinit var listView: ListView var arrayList: ArrayList= ArrayList() var adapter: MyAdapter? = null override fun onCreate(savedInstanceState: Bundle?) < super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) title = "KotlinApp" listView = findViewById(R.id.listView) arrayList.add(MyData(1, " Mashu", "987576443")) arrayList.add(MyData(2, " Azhar", "8787576768")) arrayList.add(MyData(3, " Niyaz", "65757657657")) adapter = MyAdapter(this, arrayList) listView.adapter = adapter >> //Class MyAdapter class MyAdapter(private val context: Context, private val arrayList: java.util.ArrayList) : BaseAdapter() < private lateinit var serialNum: TextView private lateinit var name: TextView private lateinit var contactNum: TextView override fun getCount(): Int < return arrayList.size >override fun getItem(position: Int): Any < return position >override fun getItemId(position: Int): Long < return position.toLong() >override fun getView(position: Int, convertView: View?, parent: ViewGroup): View? < var convertView = convertView convertView = LayoutInflater.from(context).inflate(R.layout.row, parent, false) serialNum = convertView.findViewById(R.id.serialNumber) name = convertView.findViewById(R.id.studentName) contactNum = convertView.findViewById(R.id.mobileNum) serialNum.text = " " + arrayList[position].num name.text = arrayList[position].name contactNum.text = arrayList[position].mobileNumber return convertView >> //Class MyData class MyData(var num: Int, var name: String, var mobileNumber: String)

Step 4 − Create a layout resource file row.xml and add the following code

Читайте также:  Перейти в начало страницы html

Step 5 − Add the following code to androidManifest.xml

Let’s try to run your application. I assume you have connected your actual Android Mobile device with your computer. To run the app from android studio, open one of your project’s activity files and click the Run icon from the toolbar. Select your mobile device as an option and then check your mobile device which will display your default screen.

Click here to download the project code.

Источник

Android RecylerView ListAdapter (Kotlin)

It only update items which has changed (with animation shown).

NOTE: Beware of some ListAdapter Caveats .

Fragment

class AlbumListFragment : Fragment()  private val viewModel by viewModelsAlbumListViewModel>() private lateinit var adapter: LocalAdapter override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View?  return inflater.inflate(R.layout.albumlist, container, false) > override fun onActivityCreated(savedInstanceState: Bundle?)  super.onActivityCreated(savedInstanceState)  initList() > private fun initList()  adapter = LocalAdapter(viewModel) list.adapter = adapter val items = mutableListOfViewItem>() // TODO: load items adapter.submitList(items) > sealed class ViewItem(open val id: String, val resource: Int)  data class AlbumItem(override val id: String, val title: String, val childCount: Int) : ViewItem(id, R.layout.albumlist_item) > class LocalAdapter(val viewModel: AlbumListViewModel) : ListAdapterViewItem, LocalAdapter.ViewHolder>(DiffCallback())  override fun getItemViewType(position: Int): Int  return getItem(position).resource > override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder  val view = LayoutInflater.from(parent.context) .inflate(viewType, parent, false) return ViewHolder(view) > override fun onBindViewHolder(holder: ViewHolder, position: Int)  holder.bind(getItem(position)) > private class DiffCallback: DiffUtil.ItemCallbackViewItem>()  override fun areItemsTheSame(oldItem: ViewItem, newItem: ViewItem): Boolean  if (oldItem.resource != newItem.resource) return false // check if id is the same return oldItem.id == newItem.id > @SuppressLint("DiffUtilEquals") override fun areContentsTheSame(oldItem: ViewItem, newItem: ViewItem): Boolean  // check if content is the same // equals using data class return oldItem == newItem > >  inner class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer  // why update ui here? easier to access view without need to holder.titleTextView fun bind(item: ViewItem)  when(item)  is ViewItem.AlbumItem ->  titleTextView.text = item.title detailTextView.text = "$ items" > > > >  >>

Источник

ListAdapter: Extension to RecyclerView.Adapter

ListAdapter was added in Recyclerview library version 27.1.0.

It is RecyclerView.Adapter base class for presenting List data in a RecyclerView , including computing diffs between Lists on a background thread.

Before jump into ListAdapter example, Let us see problems with below implementation.

class SampleAdapter : RecyclerView.Adapter() < var sampleList: List= Collections.emptyList() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder < val binding = SampleListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) return CustomViewHolder(binding) >override fun onBindViewHolder(holder: CustomViewHolder, position: Int) < holder.bind(sampleList.get(position)) >fun updateList(list: List) < sampleList = list notifyDataSetChanged() >override fun getItemCount(): Int < return sampleList.size >class CustomViewHolder(private val binding: SampleListItemBinding) : RecyclerView.ViewHolder(binding.root) < fun bind(sample: Sample) < binding.apply < nameItem.text = sample.name ageItem.text = sample.age.toString() >> > >

With above code, set data to adapter by adding a method like updateList() and then in the method we assign a new list and then we call notifyDataSetChanged() to update RecyclerView.

The method notifyDataSetChanged() refreshes whole list and onBindViewHolder() is called for all of the items in the list even if the item doesn’t have any change at all.

To solve above problem, We can use DiffUtil. It calculates difference between two lists(old and new) and provide the updated list to update the list.

 class SampleDiffCallback : DiffUtil.ItemCallback()

The problem is that DiffUtil calculates the difference on main thread which leads to performance issues when the adapter holds larger amount of data in the list. To avoid that, we need to run DiffUtil on background thread and pass results to the main thread.

ListAdapter provides easy way to solve all the above problems.

ListAdapter provides a method submitList(List) to provide new or modified data to RecyclerView.Adapter and handles all the diffs computation. So we don’t need to do much of setup here. All we need to do is provide a instance of DiffUtil.ItemCallback that determines whether the item is changed or not.

Here is the ListAdapter implementation

class SampleAdapter : ListAdapter(SampleItemDiffCallback()) < override fun onCreateViewHolder(parent: ViewGroup, position: Int): CustomViewHolder < val binding = SampleListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) return CustomViewHolder(binding) >override fun onBindViewHolder(holder: CustomViewHolder, position: Int) < holder.bindTo(getItem(position)) >class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) < fun bindTo(user:User)< // bind views with data >> class SampleItemDiffCallback : DiffUtil.ItemCallback() < override fun areItemsTheSame(oldItem: Sample, newItem: Sample): Boolean = oldItem == newItem override fun areContentsTheSame(oldItem: Sample, newItem: Sample): Boolean = oldItem == newItem >>

Diffs will be calculated on background thread and adapter will be notified with the results on main thread.

We can update the list to adapter using submitList() method from Activity/Fragment

adapter = SampleAdapter() listview.adapter = adapter sampleListLiveData.observe(this, Observer adapter.submitList(list) >)

Источник

Оцените статью