在Android recyclerVIew中单击项目时如何保存状态

Posted

技术标签:

【中文标题】在Android recyclerVIew中单击项目时如何保存状态【英文标题】:How to save state when item is Clicked in Android recyclerVIew 【发布时间】:2019-09-27 11:48:22 【问题描述】:

我创建了一个 recyclerView 并处理其中被点击的项目。现在我需要更改单击一项时显示的文本。首先它说“一天”,然后我点击它应该说“完成”。它起作用了,但是在我关闭并重新打开该活动后,它再次显示“一天”。那么我需要做什么才能使项目文本持久存在?

  private OnFragmentInteractionListener mListener;
    List<String> list;
    MyListAdapter adapter;
    RecyclerView recyclerView;
    String pressed="finished";
 public MainFragment() 
        // Required empty public constructor
    

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        // Inflate the layout for this fragment
        View rootView= inflater.inflate(R.layout.fragment_main, container, false);

        recyclerView=(RecyclerView)rootView.findViewById(R.id.item_list);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        list=new ArrayList<>();
        for(int i=1;i<50;i++)
            list.add("Day"+ i);
        

        adapter =new MyListAdapter(getActivity(),list,this);
        recyclerView.setAdapter(adapter);


        return rootView;

    

    @Override
    public void onDetach() 
        super.onDetach();
        mListener = null;
    

    @Override
    public void onNoteClick(int position) 
        if (position == 0) 
            Log.d(TAG, "onNoteClick: ");
            list.set(0, "finished");
            adapter.getItemId(0);


            adapter.notifyItemChanged(0);
            adapter.notifyDataSetChanged();







            Fragment fr = new Day1();
            FragmentManager fm = getFragmentManager();
            FragmentTransaction fragmentTransaction = fm.beginTransaction();
            fragmentTransaction.replace(R.id.Mainfragment1, fr,null).addToBackStack(null);
            fragmentTransaction.commit();

        

    

以及适配器代码

 Context context;
List<String>list;
public TextView textView;
public String finished="finished";
private MyViewHolder.OnNoteClickListener mOnNoteClickListener;

public MyListAdapter(Context context, List<String>list, MyViewHolder.OnNoteClickListener onNoteClickListener) 
    this.list=list;
    this.context=context;
    this.mOnNoteClickListener=onNoteClickListener;


public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
    Button textView;


    OnNoteClickListener onNoteClickListener;

    public MyViewHolder(View itemView,OnNoteClickListener onNoteClickListener) 
        super(itemView);
        textView=(Button) itemView.findViewById(R.id.textView);
        itemView.setOnClickListener(this);
        textView.setOnClickListener(this);
        this.onNoteClickListener=onNoteClickListener;


        itemView.setOnClickListener(this);
    

    @Override
    public void onClick(View v) 
        onNoteClickListener.onNoteClick(getAdapterPosition());





    



    public interface OnNoteClickListener
        void onNoteClick(int position);

    


@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) 
    View view= LayoutInflater.from(context).inflate(R.layout.layout_list_item,parent,false);
    final MyViewHolder vHolder=new MyViewHolder(view,mOnNoteClickListener);

    return vHolder;



@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) 
    holder.textView.setText(list.get(position));






@Override
public int getItemCount() 
    return list.size();

【问题讨论】:

你听说过SharedPreferences吗? 是的,谢谢,但这是针对 recyclerVIew 的,我不知道如何在 recyclerView 上实现它,我用简单的视图做了它,但它工作但我不知道 recyclerView 【参考方案1】:

您可以在arrayList中设置您点击的项目并将该数组列表保存在sharedPreference中,当您再次访问时,然后从sharedPrefrence中检索arrayList并检查arrayList中已检查项目的ID,当您设置适配器时,您可以设置签入您的适配器 onBindViewHolder 其 id 包含 arrayList 然后更改“完成”中的文本,否则将您的文本设置为“天”。

你可以创建一个 AppPreference 类:-

public class AppPreference 
    private static SharedPreferences mPreferences;
    private static SharedPreferences.Editor mPreferencesEditor;

    public static Set<String> getCamEval(Context ctx) 
            mPreferences = PreferenceManager.getDefaultSharedPreferences(ctx);
            return mPreferences.getStringSet("sdk_camEval", null);
        

        public static void setCamEval(Context ctx, ArrayList<String> value) 
            mPreferences = PreferenceManager.getDefaultSharedPreferences(ctx);
            mPreferencesEditor = mPreferences.edit();
            Set<String> set = new HashSet<>();
            set.addAll(value);
            mPreferencesEditor.putStringSet("sdk_camEval", set);
            mPreferencesEditor.commit();
        

或者您可以从项目中的任何位置调用此方法:-

保存您的列表:-

SdkPreferences.setCamEval(activity, yourList);

或获取此列表:-

iconNameList.addAll(getCamEval(this));

【讨论】:

好的,我正在更新我的答案,您可以在您的代码中应用此代码 感谢您的工作,但不能真正实现它...有什么简单的方法可以在单击的项目上保存另一个字符串或更改它的背景颜色只是为了查看它被单击一次,它应该被点击了 我无法在适配器和 vievholder 之间进行交互,这是我的问题 您可以创建一个界面来处理您的点击并将您的数据保存在您的列表中 怎么办?我觉得没有解决办法或者找不到,没人愿意帮忙,苦苦挣扎5天,搞不定【参考方案2】:

我发现了问题并使用 gSon 解决了它,并为我的 listview.bcs 创建了新的 java 类,在这种情况下,它一直在不断创建,这就是问题所在

【讨论】:

【参考方案3】:

实际上,您所做的只是更改 View,换句话说,您的适配器正在从存储数据时(即数据库)获取数据并将其显示在 recyclerView 中,所以您在这里更改的是最后一个值显示在回收器视图中,要永久更改值,您应该从回收器视图中获取位置并在视图和数据库中设置数据。

@Override
public void onNoteClick(int position) 
    if (position == 0) 
        Log.d(TAG, "onNoteClick: ");
        list.set(0, "Finished");
        adapter.getItemId(0);
        // Here make the change in the source of data
        adapter.notifyDataSetChanged();

【讨论】:

你能再解释一下吗? “list”变量是适配器中的一个局部变量,所以当适配器消失时,你在其中的所有修改都消失了,所以你需要修改你的数据源;更准确地说,当你用来自“源”的值填充“列表”时,在这个源中你也必须进行修改。希望得到帮助。 不多,但无论如何我会努力解决的,最好的问候

以上是关于在Android recyclerVIew中单击项目时如何保存状态的主要内容,如果未能解决你的问题,请参考以下文章

Android:RecyclerView 不显示片段中的列表项

Android:RecyclerView onClick 监听器没有得到

使用单击 Spinner 项刷新 ArrayList 以将新数据显示到 RecyclerView

滚动时Android RecyclerView重复项

android中RecyclerView控件的列表项横向排列

单击项目Android时RecyclerView滚动