I want to change drawable of an ImageButton in RecyclerView using CardView, depending of condition of an Object in CardView when user is scrolling through the RecyclerView (Horizontal, with SnapHelper attached).
ImageButton is in Main Activity layout and I pass it to my Custom Adapter as a parameter. In method onBindViewHolder I check the status of an Object for every drawn CardView, and if the status is '1' I want to put drawable named 'confirm', if the status is '0' the drawable should be 'cancel' on ImageButton.
This is my Main Activity layout:
<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"
android:layout_centerInParent="true"
android:background="#FFF"
android:gravity="center">
<android.support.constraint.ConstraintLayout
android:id="@+id/recyclerViewCL"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/buttonsCL"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageButton
android:id="@+id/goRight"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="8dp"
android:layout_marginBottom="32dp"
android:background="@drawable/round_button"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/direction_end_of_road_right" />
<ImageButton
android:id="@+id/goLeft"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignTop="@+id/goRight"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginStart="8dp"
android:layout_marginBottom="32dp"
android:background="@drawable/round_button"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/direction_end_of_road_left" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/searchView"
android:descendantFocusability="blocksDescendants"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.SearchView
android:id="@+id/searchView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone">
</android.support.v7.widget.SearchView>
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id="@+id/buttonsCL"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<ImageButton
android:id="@+id/setVisited"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/selectableItemBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/checked_off_bigger" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
And this is layout inflated for each of the CardView in CustomAdapter:
<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"
android:layout_gravity="center"
android:orientation="vertical"
android:paddingBottom="10dp"
tools:context=".MainActivity">
<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:clickable="true"
android:focusable="true"
android:visibility="visible"
app:cardCornerRadius="8dp"
app:cardElevation="5dp"
app:cardPreventCornerOverlap="true"
app:cardUseCompatPadding="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:focusable="false">
<TextView
android:id="@+id/studentName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginTop="24dp"
android:fontFamily="@font/roboto"
android:gravity="center_vertical"
android:text="Name"
android:textSize="24sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/beachImage" />
<ImageView
android:id="@+id/studentImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:cropToPadding="false"
android:gravity="center_vertical"
android:transitionName="image_transition"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>
This is the image to explain it more clearly:
So when user is scrolling through the RecyclerView, I want to change ImageButton's drawable - depending on the status of each CardView as user scrolls to left or right.
I've managed partially to solve the problem, but when I scroll to the right and then scroll back to the previous CardViews, the drawable is not changing or changing completely wrong as it should.
EDIT: This is my onBindViewHolder method:
...
public CustomAdapter(ArrayList<Student> studentsArray, ImageButton setStatus, ...) {
this.setVisited = setVisited; // ImageButton from MainActivity layout
this.studentsArray = studentsArray;
}
...
@Override
public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {
Student student = studentsArray.get(holder.getAdapterPosition());
TextView studentName = holder.studentNameTV;
ImageView studentImage = holder.studentImageIV;
ImageButton setStatus = setVisited;
if (student.getVisited() == 1) {
studentImage.setVisibility(View.VISIBLE);
studentImage.setImageResource(R.drawable.confirm);
setStatus.setImageResource(R.drawable.confirm);
} else if (student.getVisited() == 0) {
studentImage.setVisibility(View.VISIBLE);
studentImage.setImageResource(R.drawable.cancel);
setStatus.setImageResource(R.drawable.cancel);
}
// updates Student Visited status to Database
setVisitedTemp.setOnClickListener(view -> {
if (student.getVisited() == 0) {
studentImage.setVisibility(View.VISIBLE);
studentImage.setImageResource(R.drawable.checked);
setStatus.setVisibility(View.VISIBLE);
setStatus.setImageResource(R.drawable.checked);
DatabaseHelper dbHelper = new DatabaseHelper(mContext);
dbHelper.setVisited(student.getID(), 1);
student.setVisited(1);
//notifyItemChanged(holder.getAdapterPosition());
} else if (student.getVisited() == 1) {
studentImage.setVisibility(View.VISIBLE);
setStatus.setVisibility(View.VISIBLE);
studentImage.setImageResource(R.drawable.cancel);
setStatus.setImageResource(R.drawable.cancel);
DatabaseHelper dbHelper = new DatabaseHelper(mContext);
dbHelper.setVisited(student.getID(), 0);
student.setVisited(0);
//notifyItemChanged(holder.getAdapterPosition());
}
});
}
Check this https://medium.com/over-engineering/detecting-snap-changes-with-androids-recyclerview-snaphelper-9e9f5e95c424
Depending on current item position, obtained in activity or fragment, you can get current item from adapter, check(and change) it's data, and set correct ImageButton drawable.