0

我有一个RecyclerView有一个物品的网格。点击某个项目后,它会突出显示。
我也希望当用户向右滑动时会调用'next'方法,并且当用户向左滑动时,会调用'previous'方法。
但是,这两者并不能相互解决,因为每个人都会拦截对方的事件。
我如何让他们一起工作?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; 
    } 

因为我在OnTouch事件把return false,该项目的点击事件被解雇。但是,MouseDown事件不会在OnTouch中触发,从而阻止刷回检测(因为x1始终为0)。

+0

然而,这两个不互相奏效,因为每个拦截对方的事件,你能解释更多的这条线 –

+0

@OmarHossamEldin我的意思是,并不是所有的事件都被完全调用,因为它们会阻塞对方。问题底部添加了解释。如果还不清楚,告诉我。 – amitairos

+0

您可以在ViewPager中使用RecyclerView –

回答

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); 
     } 

请注意,您已经更新这两个项目

+0

谢谢。但问题不在于点击事件。它工作正常。问题是OnTouch事件在第一次点击时被调用,而OnClick只在第二次点击时才被调用。 – amitairos

1

OnTouch事件被称为第一前点击更改所选位置,并将OnClick只被调用在第二次点击

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

  1. 创建自己的点击收听
  2. 通话监听器,当你触摸了你的项目。
  3. 收听者将回拨至MainActivity以通知已更改的项目。
  4. 同时触摸事件将被调用。

我已在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; 
    } 
} 

定义的点击式界面:

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