简体   繁体   中英

How to change drawable of an ImageButton for every CardView individually in RecyclerView?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM