0

J'ai un RecyclerView qui a une grille d'articles. En cliquant sur un élément, il met en évidence.
Je veux aussi que lorsque l'utilisateur balaie vers la droite, une méthode 'next' soit appelée, et quand l'utilisateur balaie vers la gauche, une méthode 'précédente' est appelée.
Cependant, les deux ne fonctionnent pas les uns avec les autres, car chacun intercepte les événements de l'autre.
Comment les amener à travailler ensemble?RecyclerView lancer et l'article cliquez sur

Ceci est mon code:

RecyclerView Adaptateur

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

Fragment qui contient le 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; 
    } 

Parce que je mets return false en cas OnTouch, cliquez sur de l'article l'événement est déclenché. Toutefois, l'événement MouseDown ne se déclenche pas dans OnTouch, ce qui empêche la détection de retour de balayage (beacuse x1 est toujours 0).

+0

Cependant, les deux ne fonctionnent pas avec l'autre, comme chaque INTERCEPTIONS l'autre des événements, Pouvez-vous expliquer plus cette ligne –

+0

@OmarHossamEldin Je voulais dire que tous les événements ne sont pas complètement appelés, puisqu'ils se «bloquent» les uns les autres. Ajout d'une explication au bas de la question. Si ce n'est toujours pas clair, dites-moi. – amitairos

+0

Vous pouvez utiliser RecyclerView dans ViewPager –

Répondre

0

Essayez dans votre 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); 
     } 

Notez que vous devez changer la position sélectionnée avant la mise à jour des deux articles

+0

Merci. Mais le problème n'est pas dans l'événement click. Ça fonctionne bien. Le problème est que l'événement OnTouch est appelé au premier clic et que le OnClick est appelé uniquement au second clic. – amitairos

1

événement OnTouch est appelé le premier clic, et le OnClick est appelée uniquement sur le deuxième clic

Parce que MotionEventActions.Down et OnClick conflit. Comme une solution de contournement, je vous suggère de changer la couleur de fond à l'événement MotionEventActions.Down.

  1. Créer votre propre clic auditeur
  2. appel à l'auditeur lorsque vous atterrissez vos articles. L'écouteur rappellera MainActivity pour notifier l'élément modifié.
  3. En même temps, l'événement tactile sera appelé.

J'ai mis le OnTouchListener dans le viewholder:

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

Définie l'interface clic:

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

régler le rappel de clic dans le MainActivity pour changer la couleur de fond:

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

Note: Gardez votre doigt bouger rapidement, si la vitesse est assez lente, le MotionEventActions.Down ne sera pas appelé.

Github souce code

Capture d'écran:

enter image description here