【问题标题】:Xamarin Android: How to swipe left recyclerview itemsXamarin Android:如何向左滑动 recyclerview 项目
【发布时间】:2023-03-19 07:57:01
【问题描述】:

大家好,我叫谷口:

我有一个 recyclerview,我希望在 xamarin android 中滑动到删除,但我只能在 java 中找到文章

有谁知道如何在 C# 中做到这一点?

教如何滑动删除的java文章。

https://medium.com/@zackcosborn/step-by-step-recyclerview-swipe-to-delete-and-undo-7bbae1fce27e

我的 recylerview 适配器:

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 RecyclerView.Adapter mAdapter;
    public static bool isActionMode = true;
    private int viewType;
    private ViewGroup parent;
    public static bool unselect = false;
    private Activity mActivity;
    private MyActionMode mActionMode;
    private RecyclerView.ViewHolder holder;
    private List<time_entry> mTime_Entries;
    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<time_entry> time_entries, Context context)
    {
        mTime_Entries = time_entries;
        this.context = context;
    }

    public RecyclerAdapter(List<time_entry> time_entries, Activity activity)
    {
        mTime_Entries = time_entries;
        mActivity = activity;
    }

    public RecyclerAdapter(List<time_entry> time_entries, MyActionMode myActionMode)
    {
        mTime_Entries = time_entries;
        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 mTime_Entries.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 = mTime_Entries[position].IsSelected() ? ViewStates.Visible : ViewStates.Gone;
        myHolder.cbx.Checked = mTime_Entries[position].IsSelected();


        myHolder.mProject_Task.Text = mTime_Entries[position].projectTask;
        myHolder.mDate.Text = mTime_Entries[position].date;
        myHolder.mDescription.Text = mTime_Entries[position].description;


        myHolder.ItemView.SetBackgroundColor(mTime_Entries[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)
        {
            int position = (int)v.Tag;
            mTime_Entries[position].setSelected(!mTime_Entries[position].IsSelected());
            v.SetBackgroundColor(mTime_Entries[position].IsSelected() ? Color.LightBlue : Color.Transparent);
            v.FindViewById(Resource.Id.checkBox1).Visibility = mTime_Entries[position].IsSelected() ? ViewStates.Visible : ViewStates.Invisible;
            if (mTime_Entries[position].IsSelected())
            {
                CountAuxiliar++;
            }
            else
            {
                CountAuxiliar--;
            }
            //mode.Title = CountAuxiliar.ToString() + " " + "Selecionados";
            MainActivity.title.Text = CountAuxiliar.ToString() + " " + "Selecionados";
            Toast.MakeText(v.Context, "Click : " + CountAuxiliar + "---" + position, ToastLength.Short).Show();
        }
        if (CountAuxiliar < 1 && count == true)
        {
            count = false;
            MainActivity.toolbar2.Visibility = ViewStates.Gone;
            MainActivity.bottomnavigationview1.Visibility = ViewStates.Gone;
            MainActivity.floatinactionbutton1.Visibility = ViewStates.Visible;
        }
    }
    public void removeSelection()
    {
        if (mTime_Entries != null)
        {
            foreach (time_entry email in mTime_Entries)
            {
                email.setSelected(false);

            }
        }
       NotifyDataSetChanged();
        CountAuxiliar = 0;
        count = false;
        MainActivity.bottomnavigationview1.Visibility = ViewStates.Gone;
        MainActivity.floatinactionbutton1.Visibility = ViewStates.Visible;

    }

    public void checkall()
    {
        if (mTime_Entries != null)
        {
            foreach (time_entry email in mTime_Entries)
            {
                email.setSelected(true);

            }
        }
        NotifyDataSetChanged();
        MainActivity.bottomnavigationview1.Visibility = ViewStates.Visible;
    }


    public bool OnLongClick(View v)
    {

        if (CountAuxiliar < 1)
        {
            CountAuxiliar = 1;
            count = true;
            int position = (int)v.Tag;
            mTime_Entries[position].setSelected(!mTime_Entries[position].IsSelected());
            v.SetBackgroundColor(mTime_Entries[position].IsSelected() ? Color.LightBlue : Color.Transparent);
            MainActivity.bottomnavigationview1.Visibility = ViewStates.Visible;
            MainActivity.floatinactionbutton1.Visibility = ViewStates.Gone;
            v.FindViewById(Resource.Id.checkBox1).Visibility = mTime_Entries[position].IsSelected() ? ViewStates.Visible : ViewStates.Invisible;
            MainActivity.title.Text = CountAuxiliar.ToString() + " " + "Selecionado";

            MainActivity.toolbar2.Visibility = ViewStates.Visible;
            count = true;

            Toast.MakeText(v.Context, "Long Click : " + mTime_Entries[position].IsSelected() + "---" + position, ToastLength.Short).Show();
        }
        return true;
    }
}

【问题讨论】:

    标签: xamarin.android


    【解决方案1】:

    你可以自定义一个继承自ItemTouchHelper.SimpleCallbackSwipeToDeleteCallback来实现,这里有一个article供参考。

    SwipeToDeleteCallback 类:

    public class SwipeToDeleteCallback : ItemTouchHelper.SimpleCallback
    {
        private Context context;
        private PhotoAlbumAdapter madapter;
        private Android.Graphics.Drawables.Drawable deleteIcon;
        private int intrinsicWidth;
        private int intrinsicHeight;
        private Android.Graphics.Drawables.ColorDrawable background;
        private Color backgroundColor;
        private Paint clearPaint;
    
        public SwipeToDeleteCallback(int dragDirs, int swipeDirs, Context context) : base(dragDirs, swipeDirs )
        {
            this.context = context;
            deleteIcon = ContextCompat.GetDrawable(context, Resource.Drawable.alter_delete);
            intrinsicWidth = deleteIcon.IntrinsicWidth;
            intrinsicHeight = deleteIcon.IntrinsicHeight;
            background = new Android.Graphics.Drawables.ColorDrawable();
            backgroundColor = Color.ParseColor("#f44336");
            clearPaint = new Paint();
            clearPaint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.Clear));
        }
    
        public SwipeToDeleteCallback(int dragDirs, int swipeDirs, Context context, PhotoAlbumAdapter mRecyclerView) : this(dragDirs, swipeDirs, context)
        {
            this.context = context;
            this.madapter = mRecyclerView;
            deleteIcon = ContextCompat.GetDrawable(context, Resource.Drawable.delete);
            intrinsicWidth = deleteIcon.IntrinsicWidth;
            intrinsicHeight = deleteIcon.IntrinsicHeight;
            background = new Android.Graphics.Drawables.ColorDrawable();
            backgroundColor = Color.ParseColor("#f44336");
            clearPaint = new Paint();
            clearPaint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.Clear));
        }
    
        public override int GetMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
        {
            if(viewHolder.AdapterPosition == 10)
            {
                return 0;
            }
            return base.GetMovementFlags(recyclerView, viewHolder);
        }
    
        public override void OnChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, bool isCurrentlyActive)
        {
            base.OnChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        }
    
        public override bool OnMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
        {
            //throw new NotImplementedException();
            return false;
        }
    
        public override void OnChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, bool isCurrentlyActive)
        {
            var itemView = viewHolder.ItemView;
            var itemHeight = itemView.Bottom - itemView.Top;
            var isCanceled = dX == 0f && !isCurrentlyActive;
    
            if (isCanceled)
            {
                clearCanvas(c, itemView.Right + dX, (float)itemView.Top, (float)itemView.Right, (float)itemView.Bottom);
                base.OnChildDrawOver(c, recyclerView
                    , viewHolder, dX, dY, actionState, isCurrentlyActive);
                return;
            }
            background.Color = backgroundColor;
            background.SetBounds(itemView.Right + (int)dX, itemView.Top, itemView.Right, itemView.Bottom);
            background.Draw(c);
    
            var deleteIconTop = itemView.Top + (itemHeight - intrinsicHeight) / 2;
            var deleteIconMargin = (itemHeight - intrinsicHeight) / 2;
            var deleteIconLeft = itemView.Right - deleteIconMargin - intrinsicWidth;
            var deleteIconRight = itemView.Right - deleteIconMargin;
            var deleteIconBottom = deleteIconTop + intrinsicHeight;
    
            deleteIcon.SetBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom);
            deleteIcon.Draw(c);
    
            base.OnChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        }
    
        private void clearCanvas(Canvas c, float v, float top, float right, float bottom)
        {
            c.DrawRect(v, top, right, bottom, clearPaint);
        }
    
        public override void OnSwiped(RecyclerView.ViewHolder viewHolder, int direction)
        {
            //Invoke Removing Item method from adapter
            this.madapter.RemoveItem(viewHolder.AdapterPosition);
        }
    
        public override void ClearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
        {
            base.ClearView(recyclerView, viewHolder);
        }
    }
    

    那么在Activity中可以如下使用:

     var swipeHandler = new SwipeToDeleteCallback(0, ItemTouchHelper.Left, this, mAdapter);
     var itemTouchHelper = new ItemTouchHelper(swipeHandler);
     itemTouchHelper.AttachToRecyclerView(mRecyclerView);
    

    不要忘记在 Adapter 中添加 Remove 方法:

    public void RemoveItem (int position)
    {
        ArrayList al = new ArrayList(mPhotoAlbum.mPhotos);
        al.RemoveAt(position);
        mPhotoAlbum.mPhotos = (Photo[])al.ToArray(typeof(Photo));
        NotifyDataSetChanged();
        NotifyItemChanged(position);
    }
    

    可能是代码不完全理解,我参考这个sample来实现。 the modified sample 会在这里分享。效果如下:

    =====================================更新=========== ==========================

    从共享项目中,有两处需要修改。

    FirstRecyclerAdapter 类中的RemoveItem 方法。由于我的项目使用Object[] 设置RecycleView 的源,需要编写代码转换为@ 987654332@ 。但是,您的项目的源(mTime_Entries)也是一个 List[] ,所以不需要转换它。在您的项目中进行如下修改:

    public void RemoveItem(int position)
    {
        mTime_Entries.RemoveAt(position);
        NotifyDataSetChanged();
        NotifyItemChanged(position);
    }
    

    SecondSwipeToDeleteCallback类中的OnSwiped方法。在此之前,还需要修改SwipeToDeleteCallback构造函数。此处的适配器不正确。

      private RecyclerAdapter mdapter;
    
      public SwipeToDeleteCallback(int dragDirs, int swipeDirs, Context context, PhotoAlbumAdapter mRecyclerView) : this(dragDirs, swipeDirs, context)
    {
        this.context = context;
        this.madapter = mRecyclerView;
        deleteIcon = ContextCompat.GetDrawable(context, Resource.Drawable.delete);
        intrinsicWidth = deleteIcon.IntrinsicWidth;
        intrinsicHeight = deleteIcon.IntrinsicHeight;
        background = new Android.Graphics.Drawables.ColorDrawable();
        backgroundColor = Color.ParseColor("#f44336");
        clearPaint = new Paint();
        clearPaint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.Clear));
    }
    

    您应该在 MainActity 和此处保持它们(适配器)相同。

    那么OnSwiped可以写成一行代码如下:

    public override void OnSwiped(RecyclerView.ViewHolder viewHolder, int direction)
    {
        //Invoke Removing Item method from 
        this.mdapter.RemoveItem(viewHolder.AdapterPosition);
    }
    

    【讨论】:

    • Jiang 感谢您的回答我只是对这部分有问题
    • public void RemoveItem (int position) { ArrayList al = new ArrayList(mPhotoAlbum.mPhotos); al.RemoveAt(位置); mPhotoAlbum.mPhotos = (Photo[])al.ToArray(typeof(Photo)); NotifyDataSetChanged(); NotifyItemChanged(位置); }
    • 我是这样做的:
    • public void RemoveItem(int position) { ArrayList al = new ArrayList(MainActivity.mTime_Entries); al.RemoveAt(位置); NotifyDataSetChanged(); NotifyItemChanged(位置); }
    • 但 NotifyDataSetChanged(); 行
    猜你喜欢
    • 1970-01-01
    • 2020-09-25
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多