RecyclerView ItemTouchHelper Buttons on Swipe

后端 未结 11 1294
春和景丽
春和景丽 2020-11-27 11:05

I am trying to port some iOS functionality to Android.

I intent to create a table where on swipe to the left shows 2 button: Edit and Delete.

I have

11条回答
  •  旧时难觅i
    2020-11-27 11:10

    I am late to the party but if anyone looks for an UIKit UITableView delete button behaviour then you can use something like this with a RecyclerView in Xamarin.Android:

    public class SwipeDeleteHelper : ItemTouchHelper.Callback
    {
        private int _startingWidth = 0;
        private bool? _rightAlignedText = null;
        private bool _alreadyClicked = false;
    
        private static float _previousDx = float.NegativeInfinity;
        private static float _viewWidth = float.NegativeInfinity;
        private static float _permanentlyDeleteThreshold = float.NegativeInfinity;
    
        private static RecyclerView.ViewHolder _currentViewHolder;
        private RecyclerView.ViewHolder CurrentViewHolder
        {
            get => _currentViewHolder;
    
            set
            {
                _startingWidth = 0;
                _rightAlignedText = null;
                _alreadyClicked = false;
    
                _previousDx = float.NegativeInfinity;
    
                _currentViewHolder = value;
            }
        }
        /*
        You can create a method in a utility class for the buttonwidth conversion like this:
        public static float GetPxFromDp(float dp)
        {
            return dp * Application.Context.ApplicationContext.Resources.DisplayMetrics.Density;
        }
        Also you can use text width measurement to determine the optimal width of the button for your delete text.
        */
        public static int buttonWidth = 60 * Application.Context.ApplicationContext.Resources.DisplayMetrics.Density;
    
        public override int GetMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
        {
            if (viewHolder is EntryCell)
            {
                return MakeMovementFlags(ItemTouchHelper.ActionStateIdle, ItemTouchHelper.Left | ItemTouchHelper.Start | ItemTouchHelper.Right | ItemTouchHelper.End);
            }
    
            return MakeMovementFlags(ItemTouchHelper.ActionStateIdle, ItemTouchHelper.ActionStateIdle);
        }
    
        public override void OnSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState)
        {
            if (float.IsNegativeInfinity(_permanentlyDeleteThreshold))
            {
                _viewWidth = viewHolder.ItemView.Width;
                _permanentlyDeleteThreshold = (viewHolder.ItemView.Width * 3f / 4f);
            }
    
            if (viewHolder != CurrentViewHolder)
            {
                if (viewHolder != null) // This is a new selection and the button of the previous viewHolder should get hidden.
                {
                    (CurrentViewHolder as EntryCell)?.ResetView(CurrentViewHolder);
    
                    CurrentViewHolder = viewHolder;
                }
                else if (CurrentViewHolder != null) // This is the end of the previous selection
                {
                    var hidden = CurrentViewHolder.ItemView.FindViewById

    The EntryCell is a descendant of MvxRecyclerViewHolder and it should contain something like this:

    public class EntryCell : MvxRecyclerViewHolder
    {
        public EntryCell(View itemView, IMvxAndroidBindingContext context) : base(itemView, context)
        {
            Button _delButton = itemView.FindViewById

    Your view should have a button (Referenced in EntryCell as Resource.Id.fileListDeleteButton so the ID of the button is fileListDeleteButton) in it. I use an XML as a view and it looks like this:

    
    
    
    
    
    

    In your code, where the RecyclerView is, use it like this:

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeDeleteHelper());
    itemTouchHelper.AttachToRecyclerView(yourRecyclerView);
    

    I hope this helps someone.

提交回复
热议问题