RecyclerView fling和项目点击

时间:2017-02-19 19:51:47

标签: java android xamarin android-recyclerview android-touch-event

我的RecyclerView有一个项目网格。单击某个项目后,它会突出显示 我还想要当用户向右滑动时调用'next'方法,当用户向左滑动时,会调用'previous'方法。
但是,两者之间并没有相互影响,因为每个人都会截取对方的事件 我如何让他们一起工作?

这是我的代码:

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事件中,所以会触发项目的click事件。但是,MouseTown事件不会在OnTouch中触发,从而阻止向后扫描检测(因为x1始终为0)。

2 个答案:

答案 0 :(得分:1)

  

首次点击时会调用OnTouch事件,只有在第二次点击时才会调用OnClick

因为MotionEventActions.DownOnClick发生冲突。作为解决方法,我建议您更改MotionEventActions.Down事件的背景颜色。

  1. 创建您自己的点击监听器
  2. 当您触摸项目时,请致电听众。
  3. 监听器将回调MainActivity以通知更改的项目。
  4. 同时触摸事件将被调用。
  5. 我在视图中设置了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中设置点击回调以更改背景颜色:

      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 souce code

    屏幕截图:

    enter image description here

答案 1 :(得分: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);
        }

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