Xamarin Android:回收器视图取消选择全部,当在上下文操作模式下按后退按钮不起作用



大家好,我叫谷口。

我创建了一个回收器视图并插入了一个上下文操作模式。

当我在回收器视图上选择一个项目时,将显示上下文操作模式,并且没有选择任何项目,上下文操作模式完成。

但是,如果单击上下文操作模式上的后退按钮,则项目将保持选中状态。

我的主要活动类:

public class MainActivity : AppCompatActivity
{
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
public RecyclerView.ViewHolder holder;
public static CheckBox checkbox1;
public static BottomNavigationView bottomnavigationview1;
public static FloatingActionButton floatinactionbutton1;
public int position;
private RecyclerView.Adapter mAdapter;
private List<Email> mEmails;
private ActionMode mode;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
Xamarin.Essentials.Platform.Init(this, bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerViwer);
bottomnavigationview1 = FindViewById<BottomNavigationView>
(Resource.Id.bottom_navigation);

floatinactionbutton1 = FindViewById<FloatingActionButton>
(Resource.Id.fab);
bottomnavigationview1.Visibility = ViewStates.Gone;
mRecyclerView.AddItemDecoration(new DividerItemDecoration(mRecyclerView.Context, DividerItemDecoration.Vertical));
mRecyclerView.HasFixedSize = true;
SetupList();

//Create our layout Manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.SetLayoutManager(mLayoutManager);
RecyclerAdapter mAdapter = new RecyclerAdapter(mEmails, this);
mRecyclerView.SetAdapter(mAdapter);

}
private void SetupList()
{
for (int i = 1; i <= 2; i++)
{
mEmails = new List<Email>();
mEmails.Add(new Email() { Name = "tom", Subject = "Wanna Hang Out?", Message = "I ' ll   be around  tomorrow!!" });
mEmails.Add(new Email() { Name = "tom", Subject = "Wanna Hang Out?", Message = "I ' ll   be around  tomorrow!!" });

}
}

我的回收器视图适配器:

public class RecyclerAdapter : RecyclerView.Adapter, View.IOnClickListener, View.IOnLongClickListener
{
private View view;
private Boolean isSelected = false;
public Boolean IsSelected()
{
return isSelected;
}
public void setSelected(Boolean selected)
{
isSelected = selected;
}

public static bool unselect = false;
private Activity mActivity;
private MyActionMode mActionMode;
private List<Email> mEmails;
private Context context;
private View v;
private ActionMode mode;
public static bool count = false;
public static int CountAuxiliar = 0;
public event EventHandler<int> ItemClick;
public RecyclerAdapter(List<Email> emails, Context context)
{
mEmails = emails;
this.context = context;
}
public  RecyclerAdapter(List<Email> emails, Activity activity)
{
mEmails = emails;
mActivity = activity;
}
public class MyView : RecyclerView.ViewHolder
{
public View mMainView { get; set; }
public TextView mName { get; set; }
public TextView mSubject { get; set; }
public TextView mMessage { get; set; }
public MyView(View view) : base(view)
{
mMainView = view;
}
}
public override int ItemCount
{
get { return mEmails.Count; }
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
LayoutInflater inflater = LayoutInflater.From(parent.Context);
View row = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.row, parent, false);
RecyclerViewHolder vh = new RecyclerViewHolder(row);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
RecyclerViewHolder myHolder = holder as RecyclerViewHolder;
myHolder.cbx.Visibility = mEmails[position].IsSelected() ? ViewStates.Visible : ViewStates.Gone;
myHolder.cbx.Checked = mEmails[position].IsSelected();
if(MyActionMode.ismenuactivated == false){
myHolder.cbx.Visibility = ViewStates.Gone;
}
myHolder.mName.Text = mEmails[position].Name;
myHolder.mSubject.Text = mEmails[position].Subject;
myHolder.mMessage.Text = mEmails[position].Message;

myHolder.ItemView.SetBackgroundColor(mEmails[position].IsSelected() ? Color.LightBlue : Color.Transparent);
myHolder.ItemView.Tag = position;
myHolder.ItemView.SetOnClickListener(this);
myHolder.ItemView.SetOnLongClickListener(this);
}
void View.IOnClickListener.OnClick(View v)
{
if (CountAuxiliar > 0 && mode != null)
{
int position = (int)v.Tag;
mEmails[position].setSelected(!mEmails[position].IsSelected());
v.SetBackgroundColor(mEmails[position].IsSelected() ? Color.LightBlue : Color.Transparent);
v.FindViewById(Resource.Id.checkBox1).Visibility = mEmails[position].IsSelected() ? ViewStates.Visible : ViewStates.Invisible;
if (mEmails[position].IsSelected())
{
CountAuxiliar++;
}
else
{
CountAuxiliar--;
}
mode.Title = CountAuxiliar.ToString() + " " + "Selecionados";
Toast.MakeText(v.Context, "Click : " + CountAuxiliar + "---" + position, ToastLength.Short).Show();
}
if (CountAuxiliar < 1 && count == true)
{
count = false;
mode.Finish();
MainActivity.bottomnavigationview1.Visibility = ViewStates.Gone;
MainActivity.floatinactionbutton1.Visibility = ViewStates.Visible;
}
}
public bool OnLongClick(View v)
{
if (CountAuxiliar < 1)
{
CountAuxiliar = 1;
count = true;
int position = (int)v.Tag;
mEmails[position].setSelected(!mEmails[position].IsSelected());
v.SetBackgroundColor(mEmails[position].IsSelected() ? Color.LightBlue : Color.Transparent); MainActivity.bottomnavigationview1.Visibility = ViewStates.Visible;
MainActivity.floatinactionbutton1.Visibility = ViewStates.Gone;
v.FindViewById(Resource.Id.checkBox1).Visibility = mEmails[position].IsSelected() ? ViewStates.Visible : ViewStates.Invisible;
mActionMode = new MyActionMode(mActivity, this, position);
mode = mActivity.StartActionMode(mActionMode);
mode.Title = CountAuxiliar.ToString() + " " + "Selecionado";
count = true;
Toast.MakeText(v.Context, "Long Click : " + mEmails[position].IsSelected() + "---" + position, ToastLength.Short).Show();
}
return true;
}
}

我的上下文操作模式类:

public class MyActionMode : Java.Lang.Object, ActionMode.ICallback
{
private Activity mActivity;
private RecyclerViewHolder holder;
private Context mContext;
private RecyclerView mView;
private RecyclerView.Adapter mAdapter;
private int currentPosition;
private Button button;
public View v;
public static bool ismenuactivated = true;
private IMenu menu;
private View menuItemView;
private List<Email> mEmails;
public CheckBox cbx;
public View itemView;
private RecyclerView mRecyclerView;
public MyActionMode(Context context) : this(context, null, 0)
{
}

public MyActionMode(Context context, RecyclerView.Adapter adapter, int position)
{
mContext = context;
mAdapter = adapter;
currentPosition = position;
}
public MyActionMode(List<Email> emails, Activity activity)
{
mEmails = emails;
mActivity = activity;
}
public bool OnActionItemClicked(ActionMode mode, IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.itemOneId:
return true;
case Resource.Id.itemTwoId:
// do Update
return true;
default:
return false;
}
}
public bool OnCreateActionMode(ActionMode mode, IMenu menu)
{
mode.MenuInflater.Inflate(Resource.Menu.ContextualMenu, menu);
//------------------------------------------
button = (Button)menu.FindItem(Resource.Id.itemTwoId).ActionView;
button.Background = null;
var draw = ContextCompat.GetDrawable(mContext, Resource.Drawable.three_dots);
button.SetCompoundDrawablesWithIntrinsicBounds(draw, null, null, null);
button.Click += delegate {
PopupMenu menu1 = new PopupMenu(mContext, button);
menu1.Inflate(Resource.Menu.popup_menu);
menu1.Show();
};
return true;
}

public bool OnPrepareActionMode(ActionMode mode, IMenu menu)
{
return false;
}
public void OnDestroyActionMode(ActionMode mode)
{
mEmails[currentPosition].setSelected(false);
mView.SetBackgroundColor(Color.Transparent);
mView.FindViewById(Resource.Id.checkBox1).Visibility = ViewStates.Invisible;
mAdapter.NotifyItemChanged(currentPosition);
mode.Dispose();
}

错误发生在 OnDestroyActionMode 类上: 在行中:

mEmails[currentPosition].setSelected(false);
mView.SetBackgroundColor(Color.Transparent);
mView.FindViewById(Resource.Id.checkBox1).Visibility = ViewStates.Invisible;
mAdapter.NotifyItemChanged(currentPosition);

错误消息显示: 未处理的异常:

System.NullReferenceException:对象引用未设置为对象的实例。

当我们在上下文操作模式下按下后退按钮时,我们应该取消选择所有选项,对吗?然后我们可以像这样实现:

MyActionMode中,修改函数OnDestroyActionMode如下:

public void OnDestroyActionMode(ActionMode mode)
{
mAdapter.removeSelection();//removeSelection is a function of RecyclerAdapter  
mode.Dispose();
}

并在回收器适配器中添加功能removeSelection

public void removeSelection()
{
//assign all the value of `IsSelected` to false of mEmails list
if (mEmails!=null ) {
foreach (Email email in mEmails) {
email.setSelected(false);
}
}
NotifyDataSetChanged();
}

同时,如果我们想取消选择一些特殊位置的项目,我们可以在RecyclerAdapter中添加以下方法:

public void removeSpecialSelection(int position) {
mEmails[position].setSelected(false);
// other logic code
NotifyDataSetChanged();
}

并在方法OnDestroyActionMode中调用上述方法

public void OnDestroyActionMode(ActionMode mode)
{
// mAdapter.removeSelection();
mAdapter.removeSpecialSelection(currentPosition);
mode.Dispose();
}

最新更新