android - notifyDataSetChanged() recyclerview,只有第一个单元格点击更改

标签 android android-recyclerview

我在 fragment 中有一个 recyclerview,当用户点击它时,单元格的内容会发生变化。

用户点击该项目后,内容发生变化。但是,这只适用于第一次,但当我单击不同的行时,它们并没有改变。现在,数据源数据正在发生变化,因为如果我退出 Activity 并返回,则会显示正确的数据。为什么会这样。

我真的不明白的是,我调试的时候,我每次都通过adatper,数据是正确的,它告诉我它正在执行改变单元格外观的代码,但它并没有'实际上改变了!

这是我的 fragment :

public class AerobicFragment extends Fragment {

private static final String TAG = "999.AerobicFragment";
public static final String JSON_STRING_EXERCISES = "999.JSON_STRING_EXERCISES";
private RecyclerView exerciseRecyclerView;
private ExerciseAdapter exerciseAdapter;
public ArrayList<Exercise> exerciseList;

public static final int REQUEST_CODE_ADD_EXERCISE = 394;
private boolean aerobicExerciseSetUp;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_aerobic, container, false);

    exerciseList = new ArrayList<>();

    exerciseList = SharedPreferencesManager.getAerobicExercisesList(getContext());

    Log.d(TAG, "Aerobic Exercise List Size: " + exerciseList.size());

    aerobicExerciseSetUp = SharedPreferencesManager.getAerobicExercisesCreated(getContext());

    if(!aerobicExerciseSetUp){
        showDialog();
    }



    exerciseRecyclerView = (RecyclerView) v.findViewById(R.id.exercise_recycler_view);
    exerciseAdapter = new ExerciseAdapter(exerciseList);


    exerciseRecyclerView.setAdapter(exerciseAdapter);
    exerciseRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));


    exerciseAdapter.setOnItemClickListener(new ExerciseAdapter.ClickListener() {

        @Override
        public void onItemClick(final int position, View v) {
            Log.d(TAG, "onItemClick pos = " + position);

            int timesLeftInt = Integer.parseInt(exerciseList.get(position).getTimesPerWeek()) - exerciseList.get(position).getTimesDoneThisWeek();



            if(timesLeftInt != 0){

                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setMessage("Did you do your " + exerciseList.get(position).getNameOfExercise() +
                        " for " + exerciseList.get(position).getDurationOfExercise() + "?")
                        .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {

                                int newTimesDoneThisWeek = exerciseList.get(position).getTimesDoneThisWeek();
                                newTimesDoneThisWeek++;

                                exerciseList.get(position).setTimesDoneThisWeek(newTimesDoneThisWeek);



                                SharedPreferencesManager.setAerobicExercisesList(getContext(), exerciseList);


                                exerciseAdapter.notifyDataSetChanged();

                            }
                        })
                        .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                // User cancelled the dialog
                            }
                        });
                // Create the AlertDialog object and return it
                builder.create();
                builder.show();



            }


        }
    });




    return v;
}

private void showDialog() {

    if(!aerobicExerciseSetUp){


        AlertDialog alertDialog = new AlertDialog.Builder(getContext()).create();
        alertDialog.setTitle("No aerobic exercises are set up yet");
        alertDialog.setMessage("Do you wish to add an aerobic exercise now?");
        alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes please",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {


                        dialog.dismiss();

                        Intent intent = new Intent(getContext(), TypeOfAerobicExerciseActivity.class);
                        startActivityForResult(intent, REQUEST_CODE_ADD_EXERCISE);
                    }
                });
        alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Not now",
                new  DialogInterface.OnClickListener(){

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
        alertDialog.setCancelable(true);
        alertDialog.show();
    }


}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {


    }
    else {
    }
}



public static AerobicFragment newInstance(String text) {

    AerobicFragment f = new AerobicFragment();
    Bundle b = new Bundle();
    b.putString("msg", text);

    f.setArguments(b);

    return f;
}

这是适配器:

public class ExerciseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {


private static final String TAG = "999.ExerciseAdapter";
private static ClickListener clickListener;



public ImageView exerciseItemIcon;
public TextView exerciseNameTextView;
public TextView exerciseDurationTextView;
public TextView exerciseTimesRemainingTextView;
public TextView exerciseTimesRemainingCONSTANTTextView;

ArrayList<Exercise> exerciseArrayList = new ArrayList<>();

public ExerciseAdapter(ArrayList<Exercise> exerciseArrayList) {

    this.exerciseArrayList = exerciseArrayList;

}


public interface ClickListener {
    void onItemClick(int position, View v);
}


class ExerciseViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    public ExerciseViewHolder(View view) {
        super(view);

        view.setOnClickListener(this);

        exerciseNameTextView = (TextView)view.findViewById(R.id.exercise_name_textView);
        exerciseDurationTextView = (TextView)view.findViewById(R.id.exercise_duration_textview);
        exerciseTimesRemainingTextView = (TextView)view.findViewById(R.id.exercise_times_remaining_textview);
        exerciseItemIcon = (ImageView)view.findViewById(R.id.exercise_item_icon);
        exerciseTimesRemainingCONSTANTTextView = (TextView)view.findViewById(R.id.timesRemainingConstantTextView);
    }




    @Override
    public void onClick(View v) {
        clickListener.onItemClick(getAdapterPosition(), v);
    }


}

public void setOnItemClickListener(ClickListener clickListener) {
    ExerciseAdapter.clickListener = clickListener;
}

    @Override
    public int getItemViewType(int position) {
        // Just as an example, return 0 or 2 depending on positio

n
            // Note that unlike in ListView adapters, types don't have to be contiguous
//            return position % 2 * 2;
            return position;
        }

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

@Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {



        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.exercise_item_row, parent, false);



        return new ExerciseViewHolder(itemView);

    }




    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {


        ExerciseViewHolder exerciseViewHolder = (ExerciseViewHolder) holder;
        exerciseNameTextView.setText(exerciseArrayList.get(position).getNameOfExercise());
        exerciseDurationTextView.setText(exerciseArrayList.get(position).getDurationOfExercise());


        int timesRemainingThisWeek = Integer.parseInt(exerciseArrayList.get(position).getTimesPerWeek())
                                            - exerciseArrayList.get(position).getTimesDoneThisWeek();

        Log.d(TAG, "Times remaining: " + timesRemainingThisWeek);

        if (timesRemainingThisWeek != 0){
            exerciseTimesRemainingTextView.setText("" + timesRemainingThisWeek);
            exerciseTimesRemainingCONSTANTTextView.setVisibility(View.VISIBLE);
        }else{
            exerciseTimesRemainingTextView.setText("DONE");
            exerciseTimesRemainingCONSTANTTextView.setVisibility(View.INVISIBLE);

        }



        exerciseItemIcon.setImageResource(exerciseArrayList.get(position).getExerciseIcon());






        }
    }

这是我的项目行的 xml:

<?xml version="1.0" 

encoding="utf-8"?>

<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/card_view_exercise"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_margin="10dp"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="4dp"
    android:padding="5dp">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        >



    <ImageView
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:id="@+id/exercise_item_icon"
        android:src="@drawable/exercise_swimming_icon"
        android:padding="10dp"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center_vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Swimming"
            android:gravity="center_vertical"
            android:id="@+id/exercise_name_textView"
            android:textColor="@color/colorPrimary"
            android:textSize="18sp"
            android:padding="2dp"/>


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="20 minutes"
            android:gravity="center_vertical"
            android:id="@+id/exercise_duration_textview"
            android:textColor="@color/colorPrimary"
            android:textSize="14sp"
            android:padding="2dp"/>



    </LinearLayout>


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_vertical"
    android:paddingRight="5dp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="3"
        android:gravity="right"
        android:id="@+id/exercise_times_remaining_textview"
        android:textColor="@color/colorPrimary"
        android:textSize="30sp"
        android:padding="2dp"/>


    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="time(s) remaining"
        android:gravity="right"
        android:textColor="@color/colorPrimary"
        android:id="@+id/timesRemainingConstantTextView"
        android:textSize="14sp"
        android:padding="2dp"/>




</LinearLayout>



    </LinearLayout>


</android.support.v7.widget.CardView>

非常感谢

最佳答案

对于列表中的特定适配器位置使用

notifyItemChanged (int position)

方法。

编辑:你能用下面的代码替换你的 onBindViewHolder 方法并尝试使用它吗?

@Override
public void onBindViewHolder(final ExerciseViewHolder holder, final int position) {

    holder.exerciseNameTextView.setText(exerciseArrayList.get(position).getNameOfExercise());
    holder.exerciseDurationTextView.setText(exerciseArrayList.get(position).getDurationOfExercise());


    int timesRemainingThisWeek = Integer.parseInt(exerciseArrayList.get(position).getTimesPerWeek())
                                        - exerciseArrayList.get(position).getTimesDoneThisWeek();

    Log.d(TAG, "Times remaining: " + timesRemainingThisWeek);

    if (timesRemainingThisWeek != 0){
        holder.exerciseTimesRemainingTextView.setText("" + timesRemainingThisWeek);
        holder.exerciseTimesRemainingCONSTANTTextView.setVisibility(View.VISIBLE);
    }else{
        holder.exerciseTimesRemainingTextView.setText("DONE");
        holder.exerciseTimesRemainingCONSTANTTextView.setVisibility(View.INVISIBLE);

    }



    holder.exerciseItemIcon.setImageResource(exerciseArrayList.get(position).getExerciseIcon());

}

编辑 2:您还需要修复父类(super class)定义。将下面的代码用于适配器。

public class ExerciseAdapter extends RecyclerView.Adapter<ExerciseAdapter.ExerciseViewHolder> {


private static final String TAG = "999.ExerciseAdapter";
private static ClickListener clickListener;



public ImageView exerciseItemIcon;
public TextView exerciseNameTextView;
public TextView exerciseDurationTextView;
public TextView exerciseTimesRemainingTextView;
public TextView exerciseTimesRemainingCONSTANTTextView;

ArrayList<Exercise> exerciseArrayList = new ArrayList<>();

public ExerciseAdapter(ArrayList<Exercise> exerciseArrayList) {

    this.exerciseArrayList = exerciseArrayList;

}


public interface ClickListener {
    void onItemClick(int position, View v);
}


class ExerciseViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    public ExerciseViewHolder(View view) {
        super(view);

        view.setOnClickListener(this);

        exerciseNameTextView = (TextView)view.findViewById(R.id.exercise_name_textView);
        exerciseDurationTextView = (TextView)view.findViewById(R.id.exercise_duration_textview);
        exerciseTimesRemainingTextView = (TextView)view.findViewById(R.id.exercise_times_remaining_textview);
        exerciseItemIcon = (ImageView)view.findViewById(R.id.exercise_item_icon);
        exerciseTimesRemainingCONSTANTTextView = (TextView)view.findViewById(R.id.timesRemainingConstantTextView);
    }




    @Override
    public void onClick(View v) {
        clickListener.onItemClick(getAdapterPosition(), v);
    }


}

public void setOnItemClickListener(ClickListener clickListener) {
    ExerciseAdapter.clickListener = clickListener;
}

    @Override
    public int getItemViewType(int position) {
        // Just as an example, return 0 or 2 depending on position
            // Note that unlike in ListView adapters, types don't have to be contiguous
//            return position % 2 * 2;
            return position;
        }

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

@Override
    public ExerciseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {



        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.exercise_item_row, parent, false);



        return new ExerciseViewHolder(itemView);

    }




    @Override
    public void onBindViewHolder(final ExerciseViewHolder holder, final int position) {

    holder.exerciseNameTextView.setText(exerciseArrayList.get(position).getNameOfExercise());
    holder.exerciseDurationTextView.setText(exerciseArrayList.get(position).getDurationOfExercise());


    int timesRemainingThisWeek = Integer.parseInt(exerciseArrayList.get(position).getTimesPerWeek())
                                        - exerciseArrayList.get(position).getTimesDoneThisWeek();

    Log.d(TAG, "Times remaining: " + timesRemainingThisWeek);

    if (timesRemainingThisWeek != 0){
        holder.exerciseTimesRemainingTextView.setText("" + timesRemainingThisWeek);
        holder.exerciseTimesRemainingCONSTANTTextView.setVisibility(View.VISIBLE);
    }else{
        holder.exerciseTimesRemainingTextView.setText("DONE");
        holder.exerciseTimesRemainingCONSTANTTextView.setVisibility(View.INVISIBLE);

    }



    holder.exerciseItemIcon.setImageResource(exerciseArrayList.get(position).getExerciseIcon());

}

关于android - notifyDataSetChanged() recyclerview,只有第一个单元格点击更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47370560/

相关文章:

android - 移动后端启动器导入到android studio

Android 共享 Intent 选择器 - 仅邮件和剪贴板

android - 无法制作可执行的签名发布版本dexgaurd

android - 什么时候为 recyclerView 使用 hasStableIds true?

android - RecyclerView stackFromBottom

java - 使 3 个 View 可见,然后根据条件隐藏其他 View

android - 如何在最新版本中使用 getdownloadurl?

java - Android Java Bixolon SPP-R300 打印图像和蓝牙

java - 无休止的recyclerview,多种 View 类型,OnscrollListener后崩溃

java - 在 recyclerview 中加载选取的联系人