idanatz / OneAdapter

A Viewholderless Adapter for RecyclerView, who supports builtin diffing, states (paging, empty...), events (clicking, swiping...), and more.
MIT License
470 stars 45 forks source link

use setItem, but the onBind method not be invoke #35

Closed youngeragain closed 3 years ago

youngeragain commented 3 years ago

i use setItem(), the onBind{} not be invoke, but UI has changed a little, and then i try invoke notifyDataSetChanged() of recycleview's adapter on next line, the onBind{} is invoked. when i want to delete an item, i use the data to setItem() that has been deleted the item, but the onBind{} not working, throught i have invoke notifyDataSetChanged() on next line, like this: oneAdapterForOther?.setItems(it) sharedForOtherRecycler?.adapter?.notifyDataSetChanged()

idanatz commented 3 years ago

Sorry I didn't understand what your are trying to do or what happens, please add relevant simple code example and a clear step by step description.

DO NOT use notifyDatasetChanged with this adapter , it defeat it's whole purpose.

youngeragain commented 3 years ago

I'm sorry that my English is very poor. Could you please help me look at the documents when I send them? I set the value for the adapter in the observed data, and I call setItem() whenever my observed data changes, but it doesn't seem to work. `class ShareFragment:BaseFragment() { override var layoutId: Int = R.layout.fragment_share private var oneAdapterForOther:OneAdapter? = null private var sharedForOtherRecycler:RecyclerView? = null private val mViewModel: MainViewModel? by lazy { MainViewModel.getInstance() } override fun initView() { sharedForOtherRecycler = view?.findViewById(R.id.rv_shared_for_other)!! sharedForOtherRecycler?.layoutManager = GridLayoutManager(requireContext(), 4, GridLayoutManager.VERTICAL, false) oneAdapterForOther = OneAdapter(sharedForOtherRecycler!!) { itemModules += SharedForOtherItemHeader() itemModules += SharedForOtherItem() } oneAdapterForOther?.setItems( mutableListOf(MainViewModel.addBtn) ) }

override fun createObserver() {
    mViewModel?.apply {
        sharedForOtherData?.observe(viewLifecycleOwner){sharedForMeUserList->
            sharedForMeUserList?.let {
                oneAdapterForOther?.setItems(it)
                sharedForOtherRecycler?.adapter?.notifyDataSetChanged()
            }
        }
        cancelShareDeviceToFriendResponse?.observe(viewLifecycleOwner){response->
            response?.parse(
                    {_, _, _->
                         val tempData = mViewModel?.sharedForOtherData?.value

                            removeItem?.let {removed->
                                tempData?.remove(removed)
                            }
                            mViewModel?.sharedForOtherData?.value = tempData
                    },
                    {_, msg->
                        e(logTag, msg)
                    },
                    {msg->
                        e(logTag, msg)
                    }
                ){
                    cancelShareDeviceToFriendResponse?.postValue(null)
                }
        }
    }
}

private inner class SharedForOtherItem : ItemModule<SharedUser>() {
    init {
        config {
            layoutResource = R.layout.item_shared_for_other
        }
        onBind { model, viewBinder, _ ->
            viewBinder.findViewById<AppCompatImageView>(R.id.iv_delete_icon)?.apply {
                if(model.showDeleteIcon){
                    animate().scaleX(1f).scaleY(1f).alpha(1f).setDuration(300).withStartAction {
                        visible()
                    }.start()
                }else{
                    animate().scaleX(0f).scaleY(0f).alpha(0f).setDuration(300).withEndAction{
                        gone()
                    }.start()
                }
            }
        }
    }
}
private inner class SharedForOtherItemHeader : ItemModule<AddBtn>() {
    init {
        config {
            layoutResource = R.layout.item_shared_for_other_header
        }
        onBind { _, viewBinder, metadata ->
            viewBinder.findViewById<AppCompatImageView>(R.id.btn_add).apply {
                if(!hasOnClickListeners()){
                    setOnClickListener {
                        it.onTouchEffect()
                        addUserDialog?.show(addUserDialogBuilder)
                    }
                    setOnLongClickListener {
                        MainViewModel.isPreciseSearch = !MainViewModel.isPreciseSearch
                        return@setOnLongClickListener true
                    }
                }
            }
        }
    }
}

} `

idanatz commented 3 years ago

Please add your SharedUser and AddBtn code aswell

youngeragain commented 3 years ago

Is there a problem with my usage of these two classes? sharedUser: data class SharedUser( var id:Long, var showDeleteIcon:Boolean = false, var enableTouch:Boolean = true, var phone:String?=null, var email:String?=null, var nickname:String?="", var deviceno:String?="", var avatarUrl:String?="", val uid:String?=null, ) : Diffable { override val uniqueIdentifier: Long get() = id override fun areContentTheSame(other: Any): Boolean { return (other is SharedUser ) && (other.phone == phone) } } addBtn: data class AddBtn(var text:String):Diffable { override val uniqueIdentifier: Long get() = 0 override fun areContentTheSame(other: Any): Boolean { return true } }

idanatz commented 3 years ago

Does the setItems() doesn't work even on the first time?

oneAdapterForOther?.setItems(
      mutableListOf(MainViewModel.addBtn)
)

or only when you try to delete an item?

val tempData = mViewModel?.sharedForOtherData?.value

removeItem?.let {removed->
       tempData?.remove(removed)
}
mViewModel?.sharedForOtherData?.value = tempData
youngeragain commented 3 years ago

:) It works the first time, but it will not take effect when I try to delete one (it takes effect once in a while). My data source is the observed LiveData. I set the value through oneAdapter's setItem() every time the data source is changed, but It doesn’t seem to work correctly, all modification operations are operations on the values in that LiveData

idanatz commented 3 years ago

I've opened a new project simulating your code to try and reproduce the problem and everything works fine. Please take a look and check what is different from your implementation. https://drive.google.com/file/d/1CYfz7oxhAykWnyfgsYUMecyskMg02xNO/view?usp=sharing

youngeragain commented 3 years ago

Okay. Thank you. Let me open it later. I have some other questions about LiveData. Can I add your Email and ask some questions?

youngeragain commented 3 years ago

This is really no problem at all, but I have another problem. Normally, after I click the button, the word Delete appears on the sharedUser, but it does not appear now, and the data I observed with LiveData has changed. Can you help me see it again? https://drive.google.com/file/d/1tNXhhN2E5sAJrQMEtug79QiYl8lr9Gn8/view?usp=sharing

idanatz commented 3 years ago

sorry, I don't understand the issue I wasn't trying to implement your code, just show you an example that the setItems works as intended.

in your project,

idanatz commented 3 years ago

any updates?

youngeragain commented 3 years ago

I am a bit busy now, sorry, I will try when I have time, thank you.😊