0

私はRecyclerViewにアイテムのグリッドを持っています。アイテムをクリックすると、ハイライト表示されます。
また、ユーザーが右にスワイプすると「次の」メソッドが呼び出され、左にスワイプすると「前の」メソッドが呼び出されます。
しかし、2つはお互いにうまくいかないので、それぞれが他のイベントを傍受します。
どうやって一緒に働くのですか?RecyclerView fling and item click

これは私のコードです:

RecyclerViewアダプタ私は、OnTouchイベントでアイテムのクリックをreturn falseを入れているので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; 
    } 

が含まれてい

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

断片イベントが発生します。ただし、MouseDownイベントはOnTouchで発生せず、スワイプバック検出(beacuse x1は常に0)を防ぎます。

+0

は、2がの他のイベントの各インターセプトとして、あなたはもっとこのライン –

+0

@OmarHossamEldinを説明することができ、お互いにうまくいきません私は、彼らがお互いをブロックしているので、すべての出来事が完全に呼ばれるわけではないということを意味しました。質問の末尾に説明が追加されました。まだ明らかでない場合は、教えてください。 – amitairos

+0

RecyclerViewをViewPager内で使用することができます –

答えて

0

あなたは

+0

ありがとうございます。しかし、問題はclickイベントにはありません。それはうまく動作します。問題は、OnTouchイベントが最初のクリックで呼び出され、OnClickが2回目のクリックでのみ呼び出されることです。 – amitairos

1

OnTouchイベントが最初のクリックで呼び出され、クリック時のみ呼び出される両方の項目を更新する前に選択した位置を変更する必要があなたの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); 
     } 

お知らせでこれを試してみてください

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

関連する問題