DINA TAKLIT
DINA TAKLIT

Reputation: 8388

Kotlin RecycleView does not work correctly

I want to create a small application that once the user clicks on floating button action to add element. It will be added automatically to the top of the recycle view.

I have created for this A main activity which contains the fragment of the recycler and the add flotten.

Once the user clicks on this button a fragmented dialog is shown to insert the element. Once the user confirms i want to add the new element to the top of the recycle view.

TO did I used a global array which contains the item.

I have not implemented the logic yet for that. But what surprised me once I click on confirm button of the shown dialog the element added correctly to the global array, however, the recycle view on his own without any action on it duplicate the latest element.

I used the model view presenter for that and here are my diff classes

1.MainActivity

   class MainActivity : AppCompatActivity() {
                override fun onCreate(savedInstanceState: Bundle?) {
                    super.onCreate(savedInstanceState)
                    setContentView(R.layout.activity_main)
                    addFragment(InterFragment(), R.id.container)
                    fab.setOnClickListener { view ->
                        val dialog = IntervAddFragment()
                        val ft = supportFragmentManager.beginTransaction()
                        dialog.show(ft, ContentValues.TAG)
                    }
                }
            }

2.ADDFragmet

class IntervAddFragment : DialogFragment(), AddContract.View
{
   val presenter: AddPresenter by lazy { AddPresenter(this) }
    var dat=""
    var plom=""
    var typ=""

    override fun onCreate(savedInstanceState: Bundle?) { ....}

    override fun onStart() {.... }
    override fun onCreateView(inflater: LayoutInflater?, parent: ViewGroup?, state: Bundle?): View? {...}
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {....}
    fun  on_confirmClick()
    {
        presenter.on_confirmClick(dat,plom,typ)
        Log.e("errrr",presenter.getList().toString())
        dismiss()
    }

    fun fillSpinerPlom(view : View?) {....    }
    fun fillSpinerType(view : View?) {....    }

    private fun updateDateInView(datep:String) {....}
}

3.IntervFragement

 InterFragment: Fragment(), InterContract.View {

      var views: View? = null
         var List_inter_adapter: InterListAdapter? = null
        private var recyclerView: RecyclerView? = null
        val presenter: InterventionPresenter by lazy { InterventionPresenter(this) }

        override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                                  savedInstanceState: Bundle?): View? {.... }

        interface ClickListener {
            fun onClick(view: View, position: Int)
            fun onLongClick(view: View?, position: Int)
        }

        internal class RecyclerTouchListener(context: Context, recyclerView: RecyclerView, private val clickListener: ClickListener?) : RecyclerView.OnItemTouchListener {..... }

            override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {.....}
        override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            recyclerView = views!!.findViewById<View>(R.id.interv_item_listview) as RecyclerView
            List_inter_adapter = InterListAdapter(activity, presenter.getList(true))
            recyclerView!!.adapter = List_inter_adapter
            recyclerView!!.layoutManager = LinearLayoutManager(activity)

       }
    }

4.InterPresenter

class InterventionPresenter(val view: InterContract.View)
{
    fun getList(firstTime:Boolean): LinkedList<InterItem> {
       if(firstTime)
           return populateList().list
        else
           return items
    }

    fun populateList(): ListInter
    {
        val item1 = InterItem(1, DateT(2018, Calendar.FEBRUARY, 6).date, plomb.get(0), types.get(0))
        val  item2 = InterItem(2, DateT(2018, Calendar.MARCH, 8).date, plomb.get(1), types.get(1))
        val item3= InterItem(3, DateT(2018, Calendar.MAY, 10).date, plomb.get(2), types.get(2))
        val lstint = ListInter()
        lstint.list= LinkedList(listOf(item1, item2, item3))
        items=lstint.list
        return lstint
    }


    companion object {

        val plomb= LinkedList<String>(listOf("Dina", "Lili", "Wiseem"))
        val types= LinkedList<String>(listOf("type1","type2","type3"))
        lateinit var items: LinkedList<InterItem>
    }

}

5.ADD Presenter

class AddPresenter(val view: AddContract.View)
{
    fun on_confirmClick(date:String,plom:String,type:String)
    {
        val item= InterItem(items.size+1,date,plom,type)
            items.push(item)

    }
    fun getList(): LinkedList<InterItem> {
        return items
    }

    fun getplom(): LinkedList<String>
    { return plomb
    }
    fun getType(): LinkedList<String>
    { return types
    }
}

6.InterListAdapter

class InterListAdapter(private val context: Context, linkedList: LinkedList<InterItem>) : RecyclerView.Adapter<InterListAdapter.ViewHolder>()
{
    internal var  linkedList = LinkedList<InterItem>()
    private val inflater: LayoutInflater
    //private lateinit var listener: OnTaskSelected
    init {... }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {... }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.numero?.text=(linkedList[position].numero).toString()
        holder.date?.text=linkedList[position].date
        holder.plom?.text=linkedList[position].plom
        holder.type?.text=linkedList[position].type
    }
    override fun getItemCount(): Int {
        return linkedList.size

    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        var numero: TextView?=null
        var date: TextView?=null
        var plom: TextView?=null
        var type: TextView?=null
        var btn_delete: Button?=null
        var btn_update: Button?=null
        init {
            numero = itemView.findViewById(R.id.numero)
            date = itemView.findViewById(R.id.date)
            plom = itemView.findViewById(R.id.plom)
            type = itemView.findViewById(R.id.type)
            btn_delete = itemView.findViewById(R.id.btn_supprimer)
            btn_update = itemView.findViewById(R.id.btn_modifier)
        }
    }

}

and here is the ListInter

class ListInter

    {
        var list= LinkedList<InterItem>()
       get() = field
        set(value){field = value}
    }

Upvotes: 1

Views: 219

Answers (1)

Valentun
Valentun

Reputation: 1711

RecyclerView can't handle array change event by itself. So, you should notify it by calling the following after you've added element to array:

recyclerView.getAdapter().notifyItemInserted(items.size() - 1)

Upvotes: 3

Related Questions