Search code examples
javaandroidkotlinandroid-recyclerview

Hide / Show RecyclerView Items after Activity Button Click


I have an indeterminate list of items (override fun getItemCount() = list.size). I would like to initially show only the position 0 item to the user. After I click the "View All" button outside the recyclerview but in my activity I would like to unhide the remaining items of my list.

I can get the initial part to work in onBindViewHolder:

if (position > 0) {
view.foo.visibility  = View.GONE 
}
else {
view.foo.visibility  = View.VISIBLE 
}

but I cannot figure out how to get the remaining items to show when I click the "View All" button.

I know I need a method in my adapter and to call that method in the activity ViewAll.onclickListnener. I am just not sure what to put in the adapter method or how it interacts with the conditions inside onBindViewHolder.

Is there any simple way to just change the list.size back and forth?

kotlin preferred if possible.

Edit:

class Adapter(private var list: List<Model>) : RecyclerView.Adapter<Adapter.ViewHolder>(){

internal fun setDataSet(list: ArrayList<Model>) {
    this.list = list
}

var showAll: Boolean = false


class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    val textView: TextView = view.findViewById(R.id.textView)

}

override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {    
    val view = LayoutInflater.from(viewGroup.context)
        .inflate(R.layout.recyclerview, viewGroup, false)

    return ViewHolder(view)
}



 override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

val model = list[position]
        
if(showAll){
            println("showAll is triggered!")      
            viewHolder.textView.visibility = View.VISIBLE
            viewHolder.textView.text = model.textView
        }else{
            viewHolder.textView.text = list[0].textView
            if (viewHolder.adapterPosition > 0){
                println("this is triggered!")
                viewHolder.textView.visibility = View.GONE             
            }
        }

    println("listsize at start: $size")
}

fun updateAdapter(showAll: Boolean) {
    this.showAll = showAll
    notifyDataSetChanged()
    println("listsize after click: $size")
}

override fun getItemCount() = list.size

}

MainActivity:

buttonPlus.setOnClickListener {
adapter.updateAdapter(true)
println("button pressed")
}

buttonMinus.setOnClickListener {
adapter.updateAdapter(false)
println("button pressed")
}

XML:

<LinearLayout
android:id="@+id/mainLL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<RelativeLayout
    android:id="@+id/fooRL"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="horizontal">

    <LinearLayout
        android:id="@+id/titleLL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_gravity="center"
        tools:ignore="RelativeOverlap">

        <TextView
            android:id="@+id/title_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center_horizontal"
            android:text="@string/title />
    </LinearLayout>

    <ImageView
        android:id="@+id/buttonPlus"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerVertical="true"
        android:layout_marginStart="1dp"
        android:contentDescription="@string/buttonplus"
        android:src="@drawable/add_box_24" />

    <ImageView
        android:id="@+id/buttonMinus"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerVertical="true"
        android:layout_marginStart="1dp"
        android:contentDescription="@string/buttonminus"
        android:src="@drawable/minus_box_24"
        android:visibility="gone"/>

    </LinearLayout>
</RelativeLayout>

<LinearLayout
    android:id="@+id/headingsLL"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TableRow

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="-10dp"
                android:layout_weight="1"
                android:gravity="center"
                android:text="@string/item"
                android:textColor="@color/black"
                android:textSize="20sp"
                android:textStyle="bold" />

        </TableRow>
    </TableLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:nestedScrollingEnabled="false"
        android:background="@drawable/recyclerview_data"
        android:divider="@null"
        android:paddingBottom="12dp"
        tools:listitem="@layout/recyclerview_item" />

</LinearLayout>

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/noDataFound"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/recyclerview_data"
        android:text="@string/noDataFound"
        android:textColor="@color/black"
        android:textSize="28sp"
        android:paddingTop="10dp"
        android:paddingBottom="12dp"
        android:textAlignment="center"/>
</LinearLayout>

Model Class: data class Model(val textView: String)

Solution: I added this inside my setOnClickListeners: recyclerview?.adapter = Adapter


Solution

  • In your MainActivity (EDIT)

    val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
    val buttonPlus: Button = findViewById(R.id.buttonPlus)
    val buttonMinus: Button = findViewById(R.id.buttonMinus)
    
    
    val dataSet = ArrayList<Model>()
    dataSet.add(Model("value1"))
    dataSet.add(Model("value2"))
    dataSet.add(Model("value3"))
    dataSet.add(Model("value4"))
    
    val recyclerViewAdapter = RecyclerViewAdapter(dataSet)
    recyclerView.layoutManager = LinearLayoutManager(this)
    recyclerView.adapter = recyclerViewAdapter
    
    buttonPlus.setOnClickListener {
        recyclerViewAdapter.updateAdapter(true)
        Toast.makeText(this, "buttonPlus clicked", Toast.LENGTH_SHORT).show()
    }
    
    buttonMinus.setOnClickListener {
        recyclerViewAdapter.updateAdapter(false)
        Toast.makeText(this, "buttonMinus clicked", Toast.LENGTH_SHORT).show()
    }
    

    In RecyclerViewAdapter create a class variable to check if items should be hidden or visible and also a function to update your adapter.

    fun updateAdapter(showAll: Boolean){
        this.showAll = showAll
        notifyDataSetChanged()
    }
    

    In onBindViewHolder() hide items if the adapter position is bigger than 0.

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        if(showAll){
            holder.textView.visibility = View.VISIBLE
            holder.textView.text = list[position]
        }else{
            holder.textView.text = list[0]
            if (holder.adapterPosition > 0){
                holder.textView.visibility = View.GONE
            }
        }
    }
    

    EDIT

    in your layout/activity_main.xml

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#3D3A3A">
    
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/buttonPlus"/>
    
    <Button
        android:id="@+id/buttonPlus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/buttonMinus"
        app:layout_constraintBottom_toBottomOf="parent"/>
    
    <Button
        android:id="@+id/buttonMinus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hide"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/buttonPlus"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    in layout/recyclerview.xml

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/white"
        android:textSize="12sp" />