I need to show a list from adapter. I've got the data with calling api, but it can't showed in the interface.
this is data model Table :
data class Table(val id : String, val nama: String, val tersedia: Boolean)
this is data model Tables that contain ArrayList of Table :
data class Tables (val daftarMeja : ArrayList<Table>)
this is mu adapter :
class MejaAdapter (private val tableList: ArrayList<Table>, private val clickListener: (Table) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>(){
private lateinit var tables: Tables
override fun getItemCount(): Int {
return tableList.size
}
fun updateData(dataBaru: ArrayList<Table>) {
tableList.clear()
tableList.addAll(dataBaru)
Log.i("tableListAdapter","balbalbla" + tableList.toString())
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val cellForRow = layoutInflater.inflate(R.layout.item_meja,parent,false)
return PartViewHolder(cellForRow)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as PartViewHolder).bind(tableList[position], clickListener)
}
class PartViewHolder (itemView: View): RecyclerView.ViewHolder(itemView){
fun bind(table: Table, clicklistener: (Table) -> Unit){
itemView.tv_table_name.text = table.nama
if(table.tersedia){
itemView.container_table.setBackgroundResource(R.color.colorTableAvailable)
itemView.tv_table_name.setTextColor(Color.BLACK)
}
else {
itemView.container_table.setBackgroundResource(R.drawable.gradient)
itemView.tv_table_name.setTextColor(Color.WHITE)
}
itemView.setOnClickListener {clicklistener(table)}
}
}
}
and this fun the activity :
private lateinit var tableList: ArrayList<Tables>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_daftar_meja)
tableList = ArrayList()
/*init RecyclerView*/
recyclerView_meja.layoutManager = GridLayoutManager(this, numberOfColumns(), GridLayoutManager.VERTICAL, false)
recyclerView_meja.hasFixedSize()
/*Set Adapter*/
dataAdapter = MejaAdapter(tableItem) { tableItemClicked() }
recyclerView_meja.adapter = dataAdapter
//Show list table
val idCafe = user.cafeId
getTableList(idCafe)
}
private fun getTableList(idCafe:String){
val apiService : Service = Client.getClient()!!.create(Service::class.java)
apiService.getTable(idCafe).enqueue(object : Callback<Tables>{
override fun onResponse(call: Call<Tables>?, response: Response<Tables>?) {
Log.i("IdMeja", "id : " + response?.body())
if (response != null && response.isSuccessful) {
val listTable = response.body()
if (listTable == null) {
Toast.makeText(this#MainActivity, "Tidak ada meja", Toast.LENGTH_SHORT).show()
}
else{
tables = listTable
// update list table
Log.i("adapter", "$dataAdapter")
dataAdapter.updateData(tableList)
Toast.makeText(this#MainActivity, "hahaha$tables", Toast.LENGTH_SHORT).show()
}
}
else{
Log.i("idCafe", " $idCafe")
Toast.makeText(this#MainActivity, "Gagal dapat meja", Toast.LENGTH_SHORT).show()
}
}
override fun onFailure(call: Call<Tables>?, t: Throwable?) {
Log.i("fail",t.toString() )
Toast.makeText(this#MainActivity, "Gagal", Toast.LENGTH_SHORT).show()
}
})
}
I think the problem is in the adapter, but i don't know how to fix it.
Please help me to fix it.
We think this is a naming issue your use this line of code to name your View Holder
class MejaAdapter (private val tableList: ArrayList<Table>, private val clickListener: (Table) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>(){
Where you call it ViewHolder
Then you start using PartViewHolder
So change the code to use a consistent name PartViewHolder looks good to us
Here is our Adapter look at the naming convention used
class ViewAdapter(private val parents:List<ModelParent>):RecyclerView.Adapter<ViewAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.the_view,parent,false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return parents.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val parent = parents[position]
holder.textView.text = parent.dept
holder.recyclerView.apply {
layoutManager = LinearLayoutManager(holder.recyclerView.context, LinearLayout.VERTICAL, false)
adapter = ViewChildAdapter(parent.children)
}
}
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){
val recyclerView : RecyclerView = itemView.rv_child
val textView: TextView = itemView.textView
}
}
Related
I have a RecyclerView created in Kotlin and would like to save the data from the RecyclerView (the ArrayList) for example with GSON Libary. I've already searched a lot but can't find a working solution. Here's my current code: (without saving function)
MainActivity.kt:
class MainActivity : AppCompatActivity(), ExampleAdapter.OnItemClickListener {
private val exampleList = generateDummyList(500)
private val adapter = ExampleAdapter(exampleList, this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recycler_view.adapter = adapter
recycler_view.layoutManager = LinearLayoutManager(this)
recycler_view.setHasFixedSize(true)
}
fun insertItem(view: View) {
val index = Random.nextInt(8)
val newItem = ExampleItem(
R.drawable.ic_android,
"New item at position $index",
"Line 2"
)
exampleList.add(index, newItem)
adapter.notifyItemInserted(index)
}
fun removeItem(view: View) {
val index = Random.nextInt(8)
exampleList.removeAt(index)
adapter.notifyItemRemoved(index)
}
override fun onItemClick(position: Int) {
Toast.makeText(this, "Item $position clicked", Toast.LENGTH_SHORT).show()
val clickedItem = exampleList[position]
clickedItem.text1 = "Clicked"
adapter.notifyItemChanged(position)
}
private fun generateDummyList(size: Int): ArrayList<ExampleItem> {
val list = ArrayList<ExampleItem>()
for (i in 0 until size) {
val drawable = when (i % 3) {
0 -> R.drawable.ic_android
1 -> R.drawable.ic_audio
else -> R.drawable.ic_sun
}
val item = ExampleItem(drawable, "Item $i", "Line 2")
list += item
}
return list
}
}
ExampleItem.kt:
data class ExampleItem(val imageResource: Int, var text1: String, var text2: String)
ExampleAdapter.kt:
class ExampleAdapter(
private val exampleList: List<ExampleItem>,
private val listener: OnItemClickListener) :
RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ExampleViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.example_item,
parent, false)
return ExampleViewHolder(itemView)
}
override fun onBindViewHolder(holder: ExampleViewHolder, position: Int) {
val currentItem = exampleList[position]
holder.imageView.setImageResource(currentItem.imageResource)
holder.textView1.text = currentItem.text1
holder.textView2.text = currentItem.text2
}
override fun getItemCount() = exampleList.size
inner class ExampleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
View.OnClickListener {
val imageView: ImageView = itemView.image_view
val textView1: TextView = itemView.text_view_1
val textView2: TextView = itemView.text_view_2
init {
itemView.setOnClickListener(this)
}
override fun onClick(v: View?) {
val position = adapterPosition
if (position != RecyclerView.NO_POSITION) {
listener.onItemClick(position)
}
}
}
interface OnItemClickListener {
fun onItemClick(position: Int)
}
}
First you need to convert you Data in to json by using json object in onBindViewHolder using
String json = {"phonetype":"N95","cat":"WP"};
try {
JSONObject obj = new JSONObject(json);
Log.d("My App", obj.toString());
} catch (Throwable t) {
Log.e("My App", "Could not parse malformed JSON: \"" + json + "\"");
}
And if you want to save then you can use shared preferences.
I have recyclerView which is having multiple items. Every item is holding a checkbox to select that item. I want to get the selected item in another ArrayList and pass it to my MainActivity. On accept click I called getselecteditem() but getselecteditem() function always returns null. Here is my adapter code.
class orderAdapter(val items: List<Orders>, val context: Context) :
RecyclerView.Adapter<ViewHolder>() {
var selectedItems: ArrayList<String> = ArrayList()
var selectedList: ArrayList<String> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(context).inflate(
R.layout.order_queue_item,
parent,
false
)
)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.tvQuantity?.text = "Quantity: ${items.get(position).totalCount}"
holder.tvOrderId?.text = "Order No. : ${items.get(position).orderNumber}"
holder.tvSum?.text = "Sum: ${items.get(position).totalPrice}"
/* holder.cbSelectOrder?.setOnClickListener(object : View.OnClickListener{
override fun onClick(v: View?) {
selectedItems.add(items.get(position))
Log.e("selected"," "+selectedItems.size)
}
})*/
holder.cbSelectOrder.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
selectedList.add(items.get(position).id)
Log.e("selected", "items " + items.get(position).id)
Log.e("selected", "selected " + selectedList.size)
Log.e("selected", "selected " + selectedList.toString())
//var size = selectedItems.size
// selectedList.addAll(selectedItems)
notifyDataSetChanged()
} else if(!isChecked) {
selectedList.remove(items.get(position).id)
Log.e("selected", "items " + items.get(position).id)
Log.e("selected", "selected " + selectedList.size)
Log.e("selected", "selected " + selectedList.toString())
notifyDataSetChanged()
}
notifyDataSetChanged()
}
holder.btnView?.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
val intent = Intent(context, ReviewOrderActivity::class.java)
intent.putExtra("orderId", items.get(position).id.toString())
context.startActivity(intent) // put context infront
}
})
}
fun getSelected(): ArrayList<String> {
Log.e("selected", "selectedlist " + selectedList.size)
Log.e("selected", "selectedlist " + selectedList.toString())
return selectedList
}
override fun getItemCount(): Int {
return items.size
}
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
// Holds the TextView that will add each animal to
val tvQuantity = view.findViewById<TextView>(R.id.tv_quantity)
val tvOrderId = view.findViewById<TextView>(R.id.tv_order_id)
val tvSum = view.findViewById<TextView>(R.id.tv_sum)
val btnView = view.findViewById<Button>(R.id.btn_view)
val cbSelectOrder = view.findViewById<CheckBox>(R.id.cb_button)
}
You need a callback which lets to fetch selected order and update list on every selected or un-select order
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
....
public interface Listener {
fun getSelectedOrderList(list : ArrayList<String>);
}
}
orderAdapter constructor will have listener instance which will update selected list in main activity.
class orderAdapter(val items: List<Orders>, val context: Context, private val listener: ViewHolder.Listener)
In MainActivity recyclerview listener will get list.
recyclerView.adapter = orderAdapter(getOrderList(), this, object : ViewHolder.Listener {
override fun getSelectedOrderList(list: ArrayList<String>) {
Log.d(TAG, "Selected order List : $list")
}
})
orderAdapter class
class orderAdapter(val items: List<Orders>, val context: Context, private val listener: ViewHolder.Listener) :
RecyclerView.Adapter<ViewHolder>() {
var selectedItems: ArrayList<String> = ArrayList()
var selectedList: ArrayList<String> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(context).inflate(R.layout.order_queue_item, parent, false)
)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.tvQuantity.text = "Quantity: ${items.get(position).totalCount}"
holder.tvOrderId?.text = "Order No. : ${items.get(position).orderNumber}"
holder.tvSum?.text = "Sum: ${items.get(position).totalPrice}"
holder.cbSelectOrder.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
selectedList.add(items.get(position).id)
notifyDataSetChanged()
} else if (!isChecked) {
selectedList.remove(items.get(position).id)
notifyDataSetChanged()
}
listener.getSelectedOrderList(selectedList)
notifyDataSetChanged()
}
holder.btnView.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
Toast.makeText(context, "View Button Clicked", Toast.LENGTH_SHORT).show()
}
})
}
fun getSelected(): ArrayList<String> {
return selectedList
}
override fun getItemCount(): Int {
return items.size
}
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
// Holds the TextView that will add each animal to
val tvQuantity = view.findViewById<TextView>(R.id.tv_quantity)
val tvOrderId = view.findViewById<TextView>(R.id.tv_order_id)
val tvSum = view.findViewById<TextView>(R.id.tv_sum)
val btnView = view.findViewById<Button>(R.id.btn_view)
val cbSelectOrder = view.findViewById<CheckBox>(R.id.cb_button)
public interface Listener {
fun getSelectedOrderList(list : ArrayList<String>);
}
}
There is a delete button on my recylerview item when I click it I m showing a alert dialog when I click yes button I want to refresh my recylerview but I could'not. I call directly notifyDataSetChanged in adapter at the end of the my code but it does not work.
MyAlertDialog(In my adapter)
mAlertDialog.setPositiveButton("Yes") { dialog, id ->
val databaseHandler: DBHelper = DBHelper(holder.itemView.context)
val removedMed = Medicine(id = medicine.id,name = medicine.name,amount = medicine.amount,description = medicine.description)
databaseHandler.deleteMedicine(removedMed)
dialog.dismiss()
notifyDataSetChanged()
}
Mainactivity
class MainActivity : AppCompatActivity() {
private var adapter: MedicineAdapter? = null
private var medicineList : ArrayList<Medicine> = arrayListOf()
private var recyclerView: RecyclerView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
getDataFromDb()
}
fun getDataFromDb(){
val context = this
val db = DBHelper(context)
recyclerView = findViewById<View>(R.id.recyclerView) as RecyclerView
adapter = MedicineAdapter(this, db.readData())
val layoutManager = LinearLayoutManager(applicationContext)
recyclerView!!.layoutManager = layoutManager
recyclerView!!.itemAnimator = DefaultItemAnimator()
// set the adapter
recyclerView!!.adapter = adapter
adapter!!.notifyDataSetChanged()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
R.id.addBtn -> {
val intent = Intent(this,AddNewMedicine::class.java)
startActivity(intent)
true
}
else -> super.onOptionsItemSelected(item)
}
override fun onResume() {
super.onResume()
getDataFromDb()
}
}
MedicineAdapter
class MedicineAdapter(
private val mainActivity: MainActivity,
val medicineList: ArrayList<Medicine>)
: RecyclerView.Adapter<MedicineAdapter.ListItemHolder>(){
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int): ListItemHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.medicine_items, parent, false)
return ListItemHolder(itemView)
}
inner class ListItemHolder(view: View) :
RecyclerView.ViewHolder(view),
View.OnClickListener {
internal var name = view.findViewById<TextView>(R.id.name)
internal var amount = view.findViewById<TextView>(R.id.amount)
internal var description = view.findViewById<TextView>(R.id.description)
internal var deleteButton = view.findViewById<ImageButton>(R.id.deleteBtn)
internal var editButton = view.findViewById<ImageButton>(R.id.editBtn)
init {
view.isClickable = true
view.setOnClickListener(this)
deleteButton.setOnClickListener(this)
editButton.setOnClickListener(this)
}
override fun onClick(view: View) {
//val intentToCarPager = Intent(view!!.context, CarPagerActivity::class.java)
//view.context.startActivity(intentToCarPager)
}
}
override fun onBindViewHolder(holder: ListItemHolder, position: Int) {
val medicine = medicineList!![position]
holder.name.text = medicine.name
holder.amount.text = medicine.amount
holder.description.text = medicine.description
holder.deleteButton.setOnClickListener {
val mAlertDialog = AlertDialog.Builder(holder.itemView.context)
mAlertDialog.setTitle("Are you sure you want to this record!") //set alertdialog title
mAlertDialog.setPositiveButton("Yes") { dialog, id ->
val databaseHandler: DBHelper = DBHelper(holder.itemView.context)
val removedMed = Medicine(id = medicine.id,name = medicine.name,amount = medicine.amount,description = medicine.description)
databaseHandler.deleteMedicine(removedMed)
notifyDataSetChanged()
dialog.dismiss()
medicineList.removeAt(position)
notifyItemRemoved(position)
}
mAlertDialog.setNegativeButton("No") { dialog, id ->
}
mAlertDialog.show()
}
holder.editButton.setOnClickListener {
val dialog = UpdateMedicine(medicine)
val manager = (holder.itemView.context as MainActivity).supportFragmentManager
dialog.show(manager,"")
}
}
override fun getItemCount(): Int {
if (medicineList != null) {
return medicineList.size
}
return -1
}
}
I solved my problem by removing the object from the array
notifyDataSetChanged()
dialog.dismiss()
medicineList.removeAt(position)
notifyItemRemoved(position)
I Have NetworkRecycler class.I just want to show data to my textviews from server. I use retrofit library. In log i have error message: No adapter attached; skipping layout. Sorry for me English guys. This is my MainActivity class:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
val linearLayoutManager = LinearLayoutManager(this)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://developers.themoviedb.org/")
.build()
val json = retrofit.create(JsonPlaceHolder::class.java)
val call = json.getNetworkId(3)
call.enqueue(object: Callback<List<Network>> {
override fun onResponse(call: Call<List<Network>>, response: Response<List<Network>>) {
val network = response.body()
val networkRecycler = NetworkRecycler(network!!)
recyclerView.apply {
layoutManager = linearLayoutManager
adapter = networkRecycler
}
}
override fun onFailure(call: Call<List<Network>>, t: Throwable) {
Log.e("MainActivity", "${t.message}")
}
})
}
And this is my NetworkRecycler class:
class NetworkRecycler(private val list: List<Network>): RecyclerView.Adapter<NetworkRecycler.ViewHolder(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.recycler_list, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val network = list[position]
holder.headquarters.text = network.headquarters
holder.homepage.text = network.homepage
holder.id.text = network.id.toString()
holder.name.text = network.name
holder.originCountry.text = network.origin_country
}
override fun getItemCount(): Int = list.size
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val headquarters : TextView = itemView.findViewById(R.id.headquarters)
val homepage : TextView = itemView.findViewById(R.id.homepage)
val id : TextView = itemView.findViewById(R.id.textId)
val name : TextView = itemView.findViewById(R.id.name)
val originCountry : TextView = itemView.findViewById(R.id.origin_country)
}
}
Finally my Network class:
data class Network(
val headquarters: String,
val homepage: String,
val id: Int,
val name: String,
val origin_country: String
)
You need to set your recyclerView with adapter first, then change the adapter when get the response. This code below may be work.
//define adapter with empty list
var networkRecycler = NetworkRecycler(ArrayList<Network>())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
val linearLayoutManager = LinearLayoutManager(this)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
//set your adapter here
recyclerView.apply {
layoutManager = linearLayoutManager
adapter = networkRecycler
}
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://developers.themoviedb.org/")
.build()
val json = retrofit.create(JsonPlaceHolder::class.java)
val call = json.getNetworkId(3)
call.enqueue(object: Callback<List<Network>> {
override fun onResponse(call: Call<List<Network>>, response: Response<List<Network>>) {
val network = response.body()
networkRecycler = NetworkRecycler(network!!)
//refresh recycler view
adapter.notifyDataSetChanged();
}
override fun onFailure(call: Call<List<Network>>, t: Throwable) {
Log.e("MainActivity", "${t.message}")
}
})
}
I have been reading the different answers here on stackoverflow and tried to implement their solutions but I am still getting the error:
E/RecyclerView: No adapter attached; skipping layout
This error is logged in Log.cat .When I try to attach recyclerView Adapter in fragment .
This is the adapter which want to attached with the recyclerView
Adapter
class SubjectViewHolder(override val containerView: View):
RecyclerView.ViewHolder(containerView)
, LayoutContainer {
fun bind(subject: Subject, listener: CursorRecyclerViewAdapter.OnSubjectClickListener) {
subject_list_name.text = subject.name
subject_list_present.text = subject.present.toString()
subject_list_total.text = subject.totalClass.toString()
subject_list_delete.setOnClickListener {
Log.d(TAG,"delete button tapped. task name is ${subject.name}")
listener.onDeleteClick(subject)
}
}
}
private const val TAG="CursorViewAdapt"
class CursorRecyclerViewAdapter(private var cursor: Cursor?, private val listener: OnSubjectClickListener) :
RecyclerView.Adapter<SubjectViewHolder>(){
interface OnSubjectClickListener {
fun onDeleteClick(subject: Subject)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubjectViewHolder {
Log.d(TAG,"onSubjectViewHolder: new view requested")
val view= LayoutInflater.from(parent.context).inflate(R.layout.subject_list,parent,false)
Log.d(TAG,"onCreateViewHolder: ends")
return SubjectViewHolder(view)
}
override fun getItemCount(): Int {
Log.d(TAG,"getItemCount: starts")
val cursor=cursor// to remove the smart cast problem
val itemcount= if(cursor==null || cursor.count==0){
1
}else{
cursor.count
}
Log.d(TAG,"returning $itemcount")
return itemcount
}
override fun onBindViewHolder(holder: SubjectViewHolder, position: Int) {
Log.d(TAG, "onBindViewHolder: starts")
val cursor = cursor //avoid problems with smart cast
if (cursor == null || cursor.count == 0) {
holder.subject_list_name.setText("Instruction_heading")
} else {
if (!cursor.moveToPosition(position)) {
throw IllegalStateException("Couldn't move cursor to position $position")
}
val task = Subject(
cursor.getString(cursor.getColumnIndex(SubjectContract.Columns.SUBJECT_NAME)),
cursor.getInt(cursor.getColumnIndex(SubjectContract.Columns.TOTAL_PRESENT)),
cursor.getInt(cursor.getColumnIndex(SubjectContract.Columns.TOTAL_CLASS))
)
task.id = cursor.getLong(cursor.getColumnIndex(SubjectContract.Columns.ID))
holder.bind(task, listener)
}
}
fun swapCursor(newCursor: Cursor?): Cursor?{
if (newCursor==cursor){
return null
}
val numItems=itemCount
val oldCursor=cursor
cursor=newCursor
if (newCursor!=null){
notifyDataSetChanged()
}else{
notifyItemRangeRemoved(0,numItems)
}
return oldCursor
}
}
MainActivityFragment
private const val TAG="MainActivityFragment"
class MainActivityFragment : Fragment(),
CursorRecyclerViewAdapter.OnSubjectClickListener {
interface OnUpdate{
fun onUpdate()
}
private val viewModel by lazy { ViewModelProvider(requireActivity()).get(AttendanceViewModel::class.java) }
private val mAdapter=CursorRecyclerViewAdapter(null,this )
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG,"onCreate: starts")
super.onCreate(savedInstanceState)
viewModel.cursor.observe(this, Observer { cursor-> mAdapter.swapCursor(cursor)?.close() })
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.d(TAG,"onCreateView: called")
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_main_activity, container, false)
}
override fun onAttach(context: Context) {
Log.d(TAG,"onAttach: called")
super.onAttach(context)
if (context !is OnUpdate){
throw RuntimeException("${context.toString()} must implement OnTaskEdit")
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d(TAG,"attaching Adapter")
sli.layoutManager= LinearLayoutManager(context)
sli.adapter=mAdapter
}
override fun onDeleteClick(subject: Subject) {
viewModel.deleteSubject(subject.id)
}
}