Tony Sherman
Tony Sherman

Reputation: 295

Only Last Element added to RecyclerView in Android (Kotlin)

I am passing a list of 7 items to the recyclerview and it is only binding the last one. Through the use of logging I cal see that the getItemCount() is returning 7, but the onBindViewHolder is only being called once. I do know (again through logging) that the list that I pass to the adapter is the complete list.

Could you please help me find out why only the last element is displayed and not the whole list. Thank you.

Activity code:

class HabitActivity : AppCompatActivity() {
    var adapter: ListHabitsAdapter? = null
    private var habitList: ArrayList<Habit>? = null
    private var habitListItems: ArrayList<Habit>? = null
    private var layoutManager: RecyclerView.LayoutManager? = null

    var dbHandler:HabitDataAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_habit)

        // Initialize the Class global variables
        //val mContext = applicationContext

        dbHandler = HabitDataAdapter(this)
        habitList = ArrayList<Habit>()
        habitListItems = ArrayList()
        layoutManager = LinearLayoutManager(this)
        adapter = ListHabitsAdapter(habitListItems!!,this)

        // Set up the RecyclerView
        habitListRecyclerViewID.layoutManager = layoutManager
        habitListRecyclerViewID.adapter = adapter

        // Load the chores
        habitList = dbHandler!!.readHabits()

        habitList!!.reverse()

        for (h in habitList!!.iterator()){
            var habit = Habit()
            habit.habitName = h.habitName
            habit.habitActive = h.habitActive
            habit.habitID = h.habitID
            habitListItems!!.add(habit)

            ///adapter!!.notifyDataSetChanged()
        }
        adapter!!.notifyDataSetChanged()
        printList(habitListItems!!)
    }

    //TODO - Remove debug before production
    fun printList(list:ArrayList<Habit>){
        for (i in 0..list.size - 1){
            Log.d(DEBUG, "${list[i].habitName} has ID ${list[i].habitID}")
        }
    }

    fun addHabit(view: View) {
        var popUpResult:String?=null
        var db = HabitDataAdapter(applicationContext)

        // pop up a dialog
        var promptView:View = layoutInflater.inflate(R.layout.habit_pop_up, null)
        var builder:AlertDialog.Builder =AlertDialog.Builder(this)
        builder.setView(promptView)
        builder.setTitle("Create a Habit")
        builder.setNeutralButton("CANCEL", DialogInterface.OnClickListener({
            dialog, which -> Toast.makeText(this,"Boo",Toast.LENGTH_LONG).show()
        }))
        builder.setPositiveButton("OK", DialogInterface.OnClickListener(){
            dialog, which ->
            var habitField = promptView.editText.text.toString()
            db.createHabit(habitField)
            Toast.makeText(this,habitField,Toast.LENGTH_LONG).show()

        })

        builder.show()

    }

    fun deleteHabit(view: View) {

    }

    fun loadMain(view: View){
        var intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
    }

Here is the ListHabitAdapter:

class ListHabitsAdapter(val list:ArrayList<Habit>, context: Context): RecyclerView.Adapter<ListHabitsAdapter.ViewHolder>() {

    val mContext = context

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(mContext)
                .inflate(R.layout.habit_list_file, parent, false)

        return ViewHolder(view, mContext, list)
    }

    override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
        Log.d(DEBUG,"Starting to Bind ${list[position]}")
        holder?.bindViews(list[position])
    }

    override fun getItemCount(): Int {
        Log.d(DEBUG,"getItemCount = ${list.size}")
        return list.size
    }


    inner class ViewHolder(itemView:View, context: Context, list: ArrayList<Habit>): RecyclerView.ViewHolder(itemView), View.OnClickListener {

        var mContext = context
        var mList = list

        var habitName = itemView.findViewById<TextView>(R.id.habitNameID)
        var deleteButton = itemView.findViewById<ImageButton>(R.id.habitDeleteButton)
        var doneButton = itemView.findViewById<ImageButton>(R.id.habitActiveButton)

        fun bindViews(habit: Habit){
            habitName.text = habit.habitName

            deleteButton.setOnClickListener(this)
            doneButton.setOnClickListener(this)
        }

        override fun onClick(v: View?) {
            var mPosition:Int = adapterPosition
            var habit = mList[mPosition]

            Log.d(DEBUG, habitName.text.toString())

            when(v!!.id){
                deleteButton.id -> Log.d(DEBUG,"delete button clicked")
                doneButton!!.id -> Log.d(DEBUG,"done button clicked")
            }
        }

    }
}

The XML for the layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/habitListFileID"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageButton
            android:id="@+id/habitActiveButton"
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@android:drawable/checkbox_on_background"
            tools:layout_editor_absoluteX="2dp"
            tools:layout_editor_absoluteY="0dp" />

        <ImageButton
            android:id="@+id/habitDeleteButton"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_toEndOf="@+id/habitNameID"
            app:srcCompat="@android:drawable/btn_dialog"
            tools:layout_editor_absoluteX="327dp"
            tools:layout_editor_absoluteY="0dp" />

        <TextView
            android:id="@+id/habitNameID"
            android:layout_width="281dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="52dp"
            android:layout_marginTop="8dp"
            android:text="TextView"
            android:textSize="18sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </RelativeLayout>

</android.support.constraint.ConstraintLayout>

Upvotes: 1

Views: 809

Answers (1)

AskNilesh
AskNilesh

Reputation: 69689

as per my above comment just make your ConstraintLayout height to android:layout_height="wrap_content"

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

Upvotes: 5

Related Questions