LBJ33 LBJ33 - 3 months ago 57
Android Question

Recycler View checkbox/text issue

I have 2 problems with my current recycler view with cardview. The first is with the checkbox. The checkboxs seem to check/uncheck themselves all the time. I know I need to set onCheckedChangeListener, just not sure what to put in it. My second issue is each item in the recycler view/cardview has 4 Strings and 1 checkbox, but sometimes one of the strings is too large, which screws up the whole thing.. Is there any way if a string is too long I can make it make the cardview larger so one of the words will go underneath the first word?

Here is the custom object class:

public class Workout{

private String exercise;
private String percent;
private String reps;
private String weight;
private boolean check1;

public Workout(String exercise, String percent, String reps, String weight, boolean check1) {
this.exercise = exercise;
this.percent = percent;
this.reps = reps;
this.weight = weight;
this.check1 = check1;
}

/* accessors omitted for readability */

}


Here is the adapter:

public class MyRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> {

Context mContext;
ArrayList<Workout> workout;

public MyRecyclerAdapter(Context context, ArrayList<Workout> workout) {
mContext = context;
this.workout = workout;
}
// INITIALIZE HOLDER
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.workout_item, null);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}

//BIND DATA TO VIEWS
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Workout objWorkout = workout.get(position);
holder.exercise.setText(workout.get(position).getExercise());
holder.percent.setText(workout.get(position).getPercent());
holder.reps.setText(workout.get(position).getReps());
holder.weight.setText(workout.get(position).getWeight());
holder.check1.setOnCheckedChangeListener();

//LISTENER

holder.setItemClickListener(new ItemClickListener() {
@Override
public void onItemClick(View view, int pos) {
Toast.makeText(mContext, workout.get(pos).getExercise(),Toast.LENGTH_LONG).show();
}
});


}

@Override
public int getItemCount() {
return workout.size();
}
}


Here is the xml for custom item:

<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_width="wrap_content"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_margin="10dp"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="10dp" >


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="15dp"
android:paddingLeft="15dp"
android:paddingRight="15dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Squat"
android:textSize="20sp"
android:id="@+id/txtExercise"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="%"
android:textSize="20sp"
android:id="@+id/txtPercentage"
android:paddingLeft="30dp"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/txtExercise"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Reps"
android:textSize="20sp"
android:id="@+id/txtReps"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Weight"
android:textSize="20sp"
android:id="@+id/txtWeight"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/check1"
android:layout_toStartOf="@+id/check1"/>

<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/check1"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="31dp"
android:layout_marginEnd="31dp"
android:checked="false"/>
</RelativeLayout>




Thanks for the help!

Answer

For your check box issue:

You need to call holder.check1.setChecked(boolean) in the onBind. Keep in mind that onBind is called several times for each view. So when you scroll, and the recycler view is recycling, it is reusing a checkbox that you aren't specifying if they are checked or not.

Also, because onBind is call so frequently it is best to not set the listener there. Set the listener in the constructor of the view holder.

EDIT

In your listener store the value if it is checked or not. This is usually stored in the object that you are displaying, in your case workout. If you don't have a value there for that, you can use SparseBooleanArray. It is really good for keeping track of what is checked and not.


For your text issue:

sometimes one of the strings is too large, which screws up the whole thing

I am not too sure what you mean. But looking at your xml you do a lot things as far as layout_alignParentTop or layout_toLeftOf. I bet it is something wrong with those once one text is too large. Try changing your root layout to a LinearLayout or try to remove as many of those rules as you can. I bet you will discover your bug when doing that.

Comments