Xamarin Android:循环遍历回收器视图的所有项目以更改所有项目的颜色



大家好,我叫谷口

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

我遇到了一个问题,因为当我单击上下文操作模式的后退按钮时,选择了项目,项目保持选中状态。

我可以解决这个问题,但我有一个代码,当我选择一个项目时,这个项目的颜色会改变。现在,当我单击上下文操作模式的后退按钮时,所有项目都将取消选择,但它们保持彩色。

我希望循环遍历回收器视图的所有项目并使它们透明。 我知道唯一的方法是通过OnBindViewHolder,但是当我在removeSelection中调用OnBindViewHolder方法时,向我显示一个错误。

我的上下文操作模式:

public class MyActionMode : Java.Lang.Object, ActionMode.ICallback
{
private RecyclerView.ViewHolder holder;
private Context mContext;
private RecyclerView.Adapter mAdapter;
private int currentPosition;
private Button button;
public View mView;
private IMenu menu;
private View menuItemView;
private List<Email> mEmails;
public MyActionMode(Activity mActivity, Context context)
{
}
public MyActionMode(Context context, RecyclerView.Adapter adapter, int position, View v, List<Email> Emails)
{
mContext = context;
mAdapter = adapter;
currentPosition = position;
mView = v;
mEmails = Emails;
}

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)
{
RecyclerAdapter mAdapter = new RecyclerAdapter(mEmails, this);
mAdapter.removeSelection(mView, currentPosition);
mode.Dispose();
}
}

我的回收器视图适配器:

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;
}
private int viewType;
private ViewGroup parent;
public static bool unselect = false;
private Activity mActivity;
private MyActionMode mActionMode;
private RecyclerView.ViewHolder holder;
private List<Email> mEmails;
private Context context;
private View p;
private ActionMode mode;
public static bool count = false;
public static int CountAuxiliar = 0;
private MyActionMode myActionMode;
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 RecyclerAdapter(List<Email> mEmails, MyActionMode myActionMode)
{
this.mEmails = mEmails;
this.myActionMode = myActionMode;
}
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();

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 void removeSelection(View v,int position)
{
if (mEmails != null)
{
foreach (Email email in mEmails)
{
email.setSelected(false);
}
OnBindViewHolder(holder, position);
}
NotifyDataSetChanged();
}

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, v, mEmails);
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;
}
}

当我在我的removeSelection类上调用OnBindViewHolder时,在OnBindViewHolder类上出现此错误: System.NullReferenceException:"对象引用未设置为对象的实例。

我希望循环遍历回收器视图的所有项目并使它们透明。 我知道唯一的方法是通过OnBindViewHolder,但是当我在removeSelection中调用OnBindViewHolder方法时,我会看到一个错误。

根据您的描述,您从回收器视图中选择项目,而不是您想在单击后退按钮时取消选择此项目,对吗? 如果是,我建议您可以在删除选择方法中选择此行。

OnBindviewHolder(holder,position)

并且不要在OnBindViewHolder方法中注释掉这一行。

myHolder.ItemView.SetBackgroundColor(mEmails[position].IsSelected() ? Color.LightBlue : Color.Transparent);

感谢您的@CherryBu

我能够通过使用您的部分代码来解决此问题:

在recyclerAdapter上,我创建了一个名为removeSelection的方法:

public void removeSelection()
{
int i = 0;
if (mEmails != null)
{
foreach (Email email in mEmails)
{
email.setSelected(false);
}
}
MyActionMode.mAdapter.NotifyDataSetChanged();
CountAuxiliar = 0;
count = false;
MainActivity.bottomnavigationview1.Visibility = ViewStates.Gone;
MainActivity.floatinactionbutton1.Visibility = ViewStates.Visible;
}

行:

MyActionMode.mAdapter.NotifyDataSetChanged();

将再次绑定回收器视图,转到OnBindViewHolder方法。 在OnBindViewHolder方法上具有:

myHolder.cbx.Visibility = mEmails[position].IsSelected() ? ViewStates.Visible : ViewStates.Gone;
myHolder.ItemView.SetBackgroundColor(mEmails[position].IsSelected() ? Color.LightBlue : Color.Transparent);

方法removeSelection在上下文操作模式类的ondestroyactionmode上调用:

public void OnDestroyActionMode(ActionMode mode)
{
RecyclerAdapter mAdapter = new RecyclerAdapter(mEmails, this);
mAdapter.removeSelection();
mode.Dispose();
}

最新更新