回收者视图上下文操作模式的问题
Issue with recycler view contextual action mode
我在我的回收站视图中实现了一个上下文操作栏,长按该行。在这里,我在操作模式下为每一行显示一个复选框。并根据标志隐藏以检查它是否不是动作模式。问题是在操作模式下,只有一行显示长按复选框,其余行隐藏它。我不确定它有什么问题。我正在附加我的 Recycler 适配器 class 和相应的行 XML here。
请看一下,如果您能找到问题所在,请告诉我。
提前致谢!
正如某些机构建议的那样,在此处显示代码而不是指向 java 文件。这是代码
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
Context context;
List<RssFeed> feeds;
Database database;
FirebaseData db;
String uid;
private static final String TAG = Constants.TAG + " : " + RecyclerViewAdapter.class.getSimpleName();
public RecyclerViewAdapter(Context context, List<RssFeed> feeds) {
this.context = context;
this.feeds = feeds;
database = new Database(context);
db = new FirebaseData(context);
uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.edit_rss_feed_row, parent, false);
final RecyclerViewHolder holder = new RecyclerViewHolder(view, (Activity) context, RecyclerViewAdapter.this);
return holder;
}
@Override
public void onBindViewHolder(final RecyclerViewHolder holder, int position) {
holder.title.setText(feeds.get(position).getRssFeedTitle());
holder.address.setText(feeds.get(position).getRssFeedAddress());
if (!holder.action_mode)
holder.checkBox.setVisibility(View.GONE);
else {
holder.checkBox.setVisibility(View.VISIBLE);
holder.checkBox.setChecked(false);
}
holder.row.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle(context.getString(R.string.rss_delete_alert_title));
dialog.setMessage(context.getString(R.string.rss_delete_alert_msg));
final int position = holder.getAdapterPosition();
dialog.setNegativeButton(context.getString(R.string.no), null);
dialog.setPositiveButton(context.getString(R.string.yes), new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
RssFeed feed = feeds.get(position);
deleteFeed(feed);
feeds = new Database(context).getRssFeeds(SharedPrefUtil.getUtil(context, uid).getUserInfo());
notifyDataSetChanged();
}
});
dialog.show();
}
});
}
private void deleteFeed(RssFeed feed){
database.deleteRssFeed(feed);
db.deleteRssFeed(feed);
}
@Override
public int getItemCount() {
return feeds.size();
}
public void removeFeeds(List<RssFeed> list) {
for (RssFeed feed : list)
feeds.remove(feed);
notifyDataSetChanged();
}
class RecyclerViewHolder extends RecyclerView.ViewHolder {
TextView title;
TextView address;
RelativeLayout row;
CheckBox checkBox;
boolean action_mode = false;
ActionMode actionMode;
Activity activity;
RecyclerViewAdapter recyclerViewAdapter;
final ArrayList<RssFeed> removedList = new ArrayList<>();
public RecyclerViewHolder(View item, final Activity activity, RecyclerViewAdapter rView) {
super(item);
this.activity = activity;
recyclerViewAdapter = rView;
row = item.findViewById(R.id.row);
title = item.findViewById(R.id.rssEditFeedTitle);
address = item.findViewById(R.id.rssEditFeedAddress);
checkBox = item.findViewById(R.id.checkBox);
row.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
actionMode = ((AppCompatActivity)activity).startSupportActionMode(new ContextualCallBack(RecyclerViewHolder.this));
return true;
}
});
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (((CheckBox) v).isChecked())
removedList.add(feeds.get(getAdapterPosition()));
else removedList.remove(feeds.get(getAdapterPosition()));
}
});
}
}
class ContextualCallBack implements ActionMode.Callback {
RecyclerViewHolder holder;
ContextualCallBack(RecyclerViewHolder holder) {
this.holder = holder;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.edit_rss_feed_action_mode_menu, menu);
holder.action_mode = true;
holder.recyclerViewAdapter.notifyDataSetChanged();
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
mode.setTitle(R.string.app_name);
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int id = item.getItemId();
if (id == R.id.delete) {
holder.recyclerViewAdapter.removeFeeds(holder.removedList);
for(RssFeed feed:holder.removedList)
holder.recyclerViewAdapter.deleteFeed(feed);
holder.recyclerViewAdapter.notifyDataSetChanged();
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
holder.action_mode = false;
holder.recyclerViewAdapter.notifyDataSetChanged();
}
}
}
这里是每行 XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/row"
android:descendantFocusability="blocksDescendants"
tools:context="com.rss.feedster.rss_feedster.EditRssFeedFragment">
<EditText
android:id="@+id/rssEditFeedTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="Title RSS Feed"
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
android:textStyle="bold" />
<EditText
android:id="@+id/rssEditFeedAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/rssEditFeedTitle"
android:layout_alignLeft="@id/rssEditFeedTitle"
android:text="Description Text View"
android:textAppearance="@android:style/TextAppearance.Small" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="15dp"
android:text="Tab to remove" />
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/textView2"
android:layout_below="@+id/rssEditFeedTitle"
android:visibility="visible"/>
</RelativeLayout>
更多信息:
我忘记包括的一件事是回收器视图正在导航抽屉布局的片段中使用。
终于明白这里的错误了。我将标志 (action_mode
) 用于检查它是否是动作模式,放在 holder 对象本身内部,这意味着该标志一次只能用于单个 holder 对象(行)。当我将它移动到适配器对象时,一切都运行得很好。
我在我的回收站视图中实现了一个上下文操作栏,长按该行。在这里,我在操作模式下为每一行显示一个复选框。并根据标志隐藏以检查它是否不是动作模式。问题是在操作模式下,只有一行显示长按复选框,其余行隐藏它。我不确定它有什么问题。我正在附加我的 Recycler 适配器 class 和相应的行 XML here。 请看一下,如果您能找到问题所在,请告诉我。
提前致谢!
正如某些机构建议的那样,在此处显示代码而不是指向 java 文件。这是代码
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
Context context;
List<RssFeed> feeds;
Database database;
FirebaseData db;
String uid;
private static final String TAG = Constants.TAG + " : " + RecyclerViewAdapter.class.getSimpleName();
public RecyclerViewAdapter(Context context, List<RssFeed> feeds) {
this.context = context;
this.feeds = feeds;
database = new Database(context);
db = new FirebaseData(context);
uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.edit_rss_feed_row, parent, false);
final RecyclerViewHolder holder = new RecyclerViewHolder(view, (Activity) context, RecyclerViewAdapter.this);
return holder;
}
@Override
public void onBindViewHolder(final RecyclerViewHolder holder, int position) {
holder.title.setText(feeds.get(position).getRssFeedTitle());
holder.address.setText(feeds.get(position).getRssFeedAddress());
if (!holder.action_mode)
holder.checkBox.setVisibility(View.GONE);
else {
holder.checkBox.setVisibility(View.VISIBLE);
holder.checkBox.setChecked(false);
}
holder.row.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle(context.getString(R.string.rss_delete_alert_title));
dialog.setMessage(context.getString(R.string.rss_delete_alert_msg));
final int position = holder.getAdapterPosition();
dialog.setNegativeButton(context.getString(R.string.no), null);
dialog.setPositiveButton(context.getString(R.string.yes), new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
RssFeed feed = feeds.get(position);
deleteFeed(feed);
feeds = new Database(context).getRssFeeds(SharedPrefUtil.getUtil(context, uid).getUserInfo());
notifyDataSetChanged();
}
});
dialog.show();
}
});
}
private void deleteFeed(RssFeed feed){
database.deleteRssFeed(feed);
db.deleteRssFeed(feed);
}
@Override
public int getItemCount() {
return feeds.size();
}
public void removeFeeds(List<RssFeed> list) {
for (RssFeed feed : list)
feeds.remove(feed);
notifyDataSetChanged();
}
class RecyclerViewHolder extends RecyclerView.ViewHolder {
TextView title;
TextView address;
RelativeLayout row;
CheckBox checkBox;
boolean action_mode = false;
ActionMode actionMode;
Activity activity;
RecyclerViewAdapter recyclerViewAdapter;
final ArrayList<RssFeed> removedList = new ArrayList<>();
public RecyclerViewHolder(View item, final Activity activity, RecyclerViewAdapter rView) {
super(item);
this.activity = activity;
recyclerViewAdapter = rView;
row = item.findViewById(R.id.row);
title = item.findViewById(R.id.rssEditFeedTitle);
address = item.findViewById(R.id.rssEditFeedAddress);
checkBox = item.findViewById(R.id.checkBox);
row.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
actionMode = ((AppCompatActivity)activity).startSupportActionMode(new ContextualCallBack(RecyclerViewHolder.this));
return true;
}
});
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (((CheckBox) v).isChecked())
removedList.add(feeds.get(getAdapterPosition()));
else removedList.remove(feeds.get(getAdapterPosition()));
}
});
}
}
class ContextualCallBack implements ActionMode.Callback {
RecyclerViewHolder holder;
ContextualCallBack(RecyclerViewHolder holder) {
this.holder = holder;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.edit_rss_feed_action_mode_menu, menu);
holder.action_mode = true;
holder.recyclerViewAdapter.notifyDataSetChanged();
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
mode.setTitle(R.string.app_name);
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int id = item.getItemId();
if (id == R.id.delete) {
holder.recyclerViewAdapter.removeFeeds(holder.removedList);
for(RssFeed feed:holder.removedList)
holder.recyclerViewAdapter.deleteFeed(feed);
holder.recyclerViewAdapter.notifyDataSetChanged();
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
holder.action_mode = false;
holder.recyclerViewAdapter.notifyDataSetChanged();
}
}
}
这里是每行 XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/row"
android:descendantFocusability="blocksDescendants"
tools:context="com.rss.feedster.rss_feedster.EditRssFeedFragment">
<EditText
android:id="@+id/rssEditFeedTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="Title RSS Feed"
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
android:textStyle="bold" />
<EditText
android:id="@+id/rssEditFeedAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/rssEditFeedTitle"
android:layout_alignLeft="@id/rssEditFeedTitle"
android:text="Description Text View"
android:textAppearance="@android:style/TextAppearance.Small" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="15dp"
android:text="Tab to remove" />
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/textView2"
android:layout_below="@+id/rssEditFeedTitle"
android:visibility="visible"/>
</RelativeLayout>
更多信息: 我忘记包括的一件事是回收器视图正在导航抽屉布局的片段中使用。
终于明白这里的错误了。我将标志 (action_mode
) 用于检查它是否是动作模式,放在 holder 对象本身内部,这意味着该标志一次只能用于单个 holder 对象(行)。当我将它移动到适配器对象时,一切都运行得很好。