0

我有一个RecyclerView项目网格。单击一个项目后,它会突出显示。
我还希望当用户向右滑动时调用“下一个”方法,当用户向左滑动时调用“上一个”方法。
然而,两者并没有相互配合,因为每个人都拦截了对方的事件。
我如何让他们一起工作?

这是我的代码:

RecyclerView 适配器

public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
    {
        myHolder = holder as MyView;
        myHolder.mMainView.SetOnClickListener(this);
        if (selected_position == position)
        {
            holder.ItemView.SetBackgroundColor(Color.LightGray);
        }
        else
        {
            holder.ItemView.SetBackgroundColor(Color.Transparent);
        }
   }

public void OnClick(View v)
    {
        int position = mRecyclerView.GetChildLayoutPosition((View)sender);

        // Updating old as well as new positions
        NotifyItemChanged(selected_position);
        selected_position = position;
        NotifyItemChanged(selected_position);
    }

包含 RecyclerView 的片段

calendarRecyclerView.SetOnTouchListener(this);

public bool OnTouch(View v, MotionEvent e)
    {
        switch (e.Action)
        {
            case MotionEventActions.Down:
                x1 = e.GetX();
                break;
            case MotionEventActions.Up:
                x2 = e.GetX();
                float deltaX = x2 - x1;
                if (Math.Abs(deltaX) > MIN_DISTANCE)
                {
                    // Left to Right swipe action
                    if (x2 > x1)
                    {
                        NextMonth();
                    }

                    // Right to left swipe action               
                    else
                    {
                        PreviousMonth();
                    }
                }


                break;
        }
        return false;
    }

因为我放入return false了 OnTouch 事件,所以会触发项目的单击事件。但是,MouseDown 事件不会在 OnTouch 中触发,从而阻止了向后滑动检测(因为 x1 始终为 0)。

4

2 回答 2

1

OnTouch 事件在第一次点击时被调用,而 OnClick 仅在第二次点击时被调用

因为MotionEventActions.DownOnClick冲突。作为一种解决方法,我建议您更改MotionEventActions.Down活动的背景颜色。

  1. 创建自己的点击监听器
  2. 当你触碰你的物品时呼叫监听器。
  3. 侦听器将回调以MainActivity通知项目已更改。
  4. 同时会调用触摸事件。

OnTouchListener在视图中设置了:

public class MyViewHolder:RecyclerView.ViewHolder,IOnTouchListener
{
    private TextView textView;
    private MyItemClickListener mListener;
    private Context myContext;
    float x1 = 0;
    float x2 = 0;
    public TextView TextView { get { return textView; } }
    public MyViewHolder(View v, MyItemClickListener mItemClickListener) : base(v)
    {
        textView = v.FindViewById<TextView>(Resource.Id.itemText);
        mListener = mItemClickListener;
        v.SetOnTouchListener(this);
    }

    public MyViewHolder(View v, MyItemClickListener mItemClickListener, Context myContext) : this(v, mItemClickListener)
    {
        this.myContext = myContext;
    }
    public bool OnTouch(View v, MotionEvent e)
    {

        switch (e.Action)
        {
            case MotionEventActions.Down:
                x1 = e.GetX();
                if (mListener != null)
                {
                    mListener.OnItemClick(v, Position);
                }
                break;
            case MotionEventActions.Up:
                x2 = e.GetX();
                float deltaX = x2 - x1;
                if (Math.Abs(deltaX) > 5)
                {
                    // Left to Right swipe action
                    if (x2 > x1)
                    {
                        NextMonth(v);
                    }

                    // Right to left swipe action               
                    else
                    {
                        PreviousMonth(v);
                    }
                }
                break;
        }
        return true;           
    }

    public Boolean NextMonth(View v)
    {
        Toast.MakeText(myContext, "NextMonth called", ToastLength.Short).Show();      
        return true;
    }

    public Boolean PreviousMonth(View v)
    {
        Toast.MakeText(myContext, "PreviousMonth called", ToastLength.Short).Show();
        return true;
    }
}

定义了点击界面:

public interface MyItemClickListener
{
    void OnItemClick(View view, int postion);
}

设置点击回调MainActivity改变背景颜色:</p>

  public class MainActivity : Activity,MyItemClickListener
    { 
        RecyclerView mRecyclerView;
        RecyclerView.LayoutManager mLayoutManager;
        CustomAdapter mAdapter;
        string[] dataSet;
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            InitDataSet();
            SetContentView(Resource.Layout.Main);

            mLayoutManager = new LinearLayoutManager(this);

            mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
            mRecyclerView.SetLayoutManager(mLayoutManager);
            mAdapter = new CustomAdapter(dataSet,this);
            mAdapter.setOnItemClickListener(this);
            mRecyclerView.SetAdapter(mAdapter);

            //mRecyclerView.SetOnTouchListener(this);
        }

        public void InitDataSet()
        {
            dataSet = new string[60];
            for (int i = 0; i < 60; i++)
            {
                dataSet[i] = "This is element #" + i;
            }
        }

        public void OnItemClick(View view, int postion)
        {
            mAdapter.NotifyItemChanged(CustomAdapter.selected_position);
            CustomAdapter.selected_position = postion;
            mAdapter.NotifyItemChanged(postion);
        }
     }
   }

注意:保持手指快速移动,如果速度足够慢MotionEventActions.Down则不会被调用。

Github 源代码

截屏:

在此处输入图像描述

于 2017-02-20T09:00:38.280 回答
0

在你的 onClick 中试试这个

    public void OnClick(View v)
        {
            int position = mRecyclerView.GetChildLayoutPosition((View)sender);
            int oldPosition = selectedPosition;
            selected_position = position;
            // Updating old as well as new positions
            NotifyItemChanged(oldPosition);

            NotifyItemChanged(selected_position);
        }

请注意,您必须在更新这两个项目之前更改所选位置

于 2017-02-19T20:35:57.860 回答