关闭应用程序或切换片段时,将选定的项目保存在RecyclerView中

时间:2018-07-21 13:43:48

标签: java android android-recyclerview sharedpreferences

我的片段中有一个Recycler View,它在单击某个项目时会打开活动,而在长时间单击时会突出显示该项目。但是,当我切换片段或关闭我的应用程序并重新打开它时,我希望先前选择的项目保持选中状态。我想这是通过Shared Preferences完成的,但是如何保存所选项目然后再次填充?

这是我的自定义适配器。 TextViews onBindViewHolder 中选择:

public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder> {

private ArrayList<Workout> mExampleList;
private OnItemClickListener mListener;

public interface OnItemClickListener {
    void onItemClick(int position);

}

public void setOnItemClickListener(OnItemClickListener listener) {
    mListener = listener;
}

public static class ExampleViewHolder extends RecyclerView.ViewHolder {

    public TextView mTextView1,mTextView2,mTextView3,mTextView4;
    CardView mCardView;

    public ExampleViewHolder(View itemView, final OnItemClickListener listener) 
{
        super(itemView);

        mTextView1 = itemView.findViewById(R.id.listTextView1);
        mTextView2 = itemView.findViewById(R.id.listTextView2);
        mTextView3 = itemView.findViewById(R.id.listTextView3);
        mTextView4 = itemView.findViewById(R.id.listTextView4);

        mCardView = itemView.findViewById(R.id.cardView);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(listener != null) {
                    int position = getAdapterPosition();
                    if (position != RecyclerView.NO_POSITION) {
                        listener.onItemClick(position);
                    }
                }
            }
        });
    }
}

public ExampleAdapter(ArrayList<Workout> exampleList) {
    mExampleList = exampleList;
}

@NonNull
@Override
public ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_item,parent,false);

    ExampleViewHolder evh = new ExampleViewHolder(v, mListener);

    return evh;
}

@Override
public void onBindViewHolder(@NonNull final ExampleViewHolder holder, final int position) {
    Workout workout = mExampleList.get(position);

    holder.mTextView1.setText(workout.getText1());
    holder.mTextView2.setText(workout.getText2());
    holder.mTextView3.setText(workout.getText3());
    holder.mTextView4.setText(workout.getText4());

    holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
            if(holder.mTextView1.isSelected()) {
                holder.mTextView1.setSelected(false);
                holder.mTextView2.setSelected(false);
                holder.mTextView3.setSelected(false);
                holder.mTextView4.setSelected(false);
            } else {
                holder.mTextView1.setSelected(true);
                holder.mTextView2.setSelected(true);
                holder.mTextView3.setSelected(true);
                holder.mTextView4.setSelected(true);
            }
            return true;
        }
    });

}

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

这是我的片段:

public class HomeFragment extends Fragment implements View.OnClickListener{

private RecyclerView mRecyclerView;
private ExampleAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
ArrayList<Workout> exampleList;

MainActivity mainActivity;
DataModel dataModel = new DataModel();

View rootView;

private TextView[] textViews;
private CardView[] cardViews;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    rootView = inflater.inflate(R.layout.fragment_home,container,false);

    mainActivity = (MainActivity) getActivity();
    mainActivity.setToolbarName("Workouts");

    textViews = new TextView[16];
    cardViews = new CardView[3];

    for(int i=0; i<textViews.length; i++) {
        {
            String buttonID = "textView" + (i+1);

            int resID = getResources().getIdentifier(buttonID, "id", getActivity().getPackageName());
            textViews[i] = ((TextView) rootView.findViewById(resID));
        }
    }

    updateWeekText();

    textViews[2].setText(roundDecimals(mainActivity.getBenchMax()));
    textViews[4].setText(roundDecimals(mainActivity.getSquatMax()));
    textViews[6].setText(roundDecimals(mainActivity.getDeadliftMax()));
    textViews[8].setText(roundDecimals(mainActivity.getPressMax()));

    Button buttonNextWeek = rootView.findViewById(R.id.buttonNextWeek);
    buttonNextWeek.setOnClickListener(this);

    int week = MainActivity.getWeekNumber();

    exampleList = new ArrayList<>();
    if(week == 1 || week == 2 || week == 3 || week == 4){
        exampleList.add(new Workout("Day 1", "C-S", "C-B", "Rack Pulls"));
        exampleList.add(new Workout("Day 2", "2ct Paused Squat", "C-P", "Pendlay Row"));
        exampleList.add(new Workout("Day 3", "C-D", "Floor Press", "Leg Press"));
    } else {
        exampleList.add(new Workout("Day 1", "C-S", "C-B", "2ct Paused Deadlift"));
        exampleList.add(new Workout("Day 2", "Pin Squat", "C-P", "Pendlay Row"));
        exampleList.add(new Workout("Day 3", "C-D", "2ct Paused Bench", "303 Tempo Squat"));
    }

    buildRecyclerView();

    return rootView;
}

public void buildRecyclerView() {
    mRecyclerView = rootView.findViewById(R.id.recyclerView);
    mRecyclerView.setHasFixedSize(true);
    mLayoutManager = new LinearLayoutManager(getContext());
    mAdapter = new ExampleAdapter(exampleList);

    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setAdapter(mAdapter);

    mAdapter.setOnItemClickListener(new ExampleAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(int position) {
            if (position == 0) {
                startActivity(new Intent(getActivity(),ActivityDay1.class));
            }
            if (position == 1) {
                startActivity(new Intent(getActivity(),ActivityDay2.class));
            }
        }
    });
}

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.buttonNextWeek:
            createDialog();
            break;
    }
}

private void updateWeekText() {
    textViews[9].setText("Current week: "+String.valueOf(mainActivity.getWeekNumber()));
}

private void createDialog(){
    int nextWeek = mainActivity.getWeekNumber()+1;

    AlertDialog.Builder builder;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        builder = new AlertDialog.Builder(getContext(), android.R.style.Theme_Material_Dialog_Alert);
    } else {
        builder = new AlertDialog.Builder(getContext());
    }
    builder.setTitle("Start week "+nextWeek+"?")
            .setMessage("Are you sure?")
            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    mainActivity.setWeekNumber(mainActivity.getWeekNumber()+1);
                    updateWeekText();
                }
            })
            .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // do nothing
                }
            })
            .setIcon(R.drawable.ic_navigate_next_black_24dp)
            .show();
}

public String roundDecimals(double a){
    NumberFormat nf = new DecimalFormat("##.###");
    return nf.format(a);
}

我们将不胜感激。
让我知道是否需要更多代码。

1 个答案:

答案 0 :(得分:0)

您需要先修复适配器实现中的一些错误。

isCompleted布尔字段添加到您的Workout类中。使用当前的适配器实现,仅通过滚动recyclerView即可弄乱“已选择”状态,因为您不存储值,只能更改ViewHolder状态。

LongLickListener的正文移至ViewHolder的新方法中:

void setSelected(boolean selected){
    mTextView1.setSelected(selected);
    mTextView2.setSelected(selected);
    mTextView3.setSelected(selected);
    mTextView4.setSelected(selected);
}

现在您可以将LongClickListener更改为:

@Override
public boolean onLongClick(View view) {
    workout.isCompleted = !workout.isCompleted;
    holder.setSelected(workout.isCompleted);
    return true;
}

通过这种方式,锻炼完成的状态实际上存储在数据列表中。为确保视图状态正确,请将此行添加到您的onBindViewHolder

holder.setSelected(workout.isCompleted);

否则,先前绑定到“已完成”锻炼的ViewHolder在显示“未完成”锻炼时将错误显示。

对于存储所选项目-这有点棘手,因为它主要是持久性/数据库设计问题。

  • 您的Workout项目仅仅是锻炼的定义吗?
  • 他们会复发吗?
  • 用户可以添加/删除锻炼定义吗?
  • 有完整的锻炼历史吗?还是每天重置?

您至少需要为每个锻炼定义一些稳定的ID才能正确持久化它们,然后建议您使用原始的SQLiteRoomRealm查看数据库实现