Java 回收浏览并点击物品

Java 回收浏览并点击物品,java,android,xamarin,android-recyclerview,android-touch-event,Java,Android,Xamarin,Android Recyclerview,Android Touch Event,我有一个RecyclerView,它有一个项目网格。单击某个项目时,它会高亮显示。 我还希望当用户向右滑动时,调用“下一步”方法,当用户向左滑动时,调用“上一步”方法。 但是,这两种方法彼此不起作用,因为它们都截取对方的事件。 我如何让他们一起工作 这是我的代码: 回收视图适配器 public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) { myHolder =

我有一个
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;
    }

因为我在OnTouch事件中放入了
return false
,所以触发了该项目的click事件。但是,MouseDown事件不会在OnTouch中触发,从而阻止刷回检测(因为x1始终为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);
        }
请注意,在更新这两个项目之前,必须更改选定的位置

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

因为
MotionEventActions.Down
OnClick
冲突。作为一种解决方法,我建议您更改
MotionEventActions.Down
事件的背景色

  • 创建自己的单击侦听器
  • 当你触碰你的物品时,给听众打电话
  • 侦听器将回调到
    MainActivity
    ,以通知已更改的项
  • 同时,将调用触摸事件
  • 我已在viewholder中设置了
    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;
        }
    }
    
    main活动
    中设置单击回调以更改背景颜色:

      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);
            }
         }
       }
    
    public类main活动:活动,MyItemClickListener
    { 
    回收视图mRecyclerView;
    RecyclerView.LayoutManager mllayoutmanager;
    定制适配器mAdapter;
    字符串[]数据集;
    创建时受保护的覆盖无效(捆绑包)
    {
    base.OnCreate(bundle);
    InitDataSet();
    SetContentView(Resource.Layout.Main);
    mLayoutManager=新的LinearLayoutManager(此);
    mRecyclerView=findviewbyd(Resource.Id.recyclerView);
    mRecyclerView.SetLayoutManager(mllayoutmanager);
    mAdapter=新的CustomAdapter(数据集,此);
    mAdapter.setOnItemClickListener(本);
    mRecyclerView.SetAdapter(mAdapter);
    //mRecyclerView.SetOnTouchListener(这个);
    }
    公共void InitDataSet()
    {
    数据集=新字符串[60];
    对于(int i=0;i<60;i++)
    {
    数据集[i]=“这是元素#”+i;
    }
    }
    公共空白位置单击(视图、内部位置)
    {
    mAdapter.NotifyItemChanged(CustomAdapter.selected_位置);
    CustomAdapter.selected_position=position;
    mAdapter.NotifyItemChanged(职位);
    }
    }
    }
    
    注意:保持手指快速移动,如果速度足够慢,则不会调用
    MotionEventActions.Down

    屏幕截图:


    然而,这两种方法彼此不协调,因为它们都截取对方的事件,您能对此进行更多解释吗line@OmarHossamEldin我的意思是,并不是所有的事件都被完全调用,因为它们彼此“阻塞”。在问题的底部添加了解释。如果仍然不清楚,请告诉我。您可以使用ViewPagerAs中的RecyclerView作为开始,您需要在
    NextMonth
    PreviousMonth
    返回true之后添加,然后,您必须记录这些值,以检查您的值是如何计算的,以及它是否符合您的头脑或大脑中的需要not@OmarHossamEldin我在你说的地方加上了returntrue。现在,NextMonth和PreviousMonth都被调用,但是您必须在某个项目上单击两次才能突出显示。谢谢。但问题不在于点击事件。它很好用。问题是OnTouch事件在第一次单击时被调用,而OnClick仅在第二次单击时被调用。
      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);
            }
         }
       }