2015-04-17 10 views
8

W naszej aplikacji mamy listę wiadomości. Przechodzimy do RecyclerView. Nasze wiadomości mogą składać się z tekstów, obrazów. Przykładowy komunikat może wyglądać tak: enter image description hereJak obsługiwać wiele kliknięć układu w recyklerzeZobacz w Androidzie

Aby obsłużyć kliknięć użyć tej klasy:

public class RecyclerViewItemClickListener implement RecyclerView.OnItemTouchListener { 

    public static interface OnItemClickListener { 
     public void onItemClick(View view, int position); 
     public void onItemLongClick(View view, int position); 
    } 

    private OnItemClickListener mListener; 
    private GestureDetector mGestureDetector; 

    public RecyclerViewItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) { 
     mListener = listener; 
     mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { 
      @Override 
      public boolean onSingleTapUp(MotionEvent e) { 
       return true; 
      } 

      @Override 
      public void onLongPress(MotionEvent e) 
      { 
       View childView = recyclerView.findChildViewUnder(e.getX(), e.getY()); 
       if(childView != null && mListener != null) 
       { 
        mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView)); 
       } 
      } 
     }); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) { 
     View childView = view.findChildViewUnder(e.getX(), e.getY()); 
     if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { 
      mListener.onItemClick(childView, view.getChildAdapterPosition(childView)); 
     } 
     return false; 
    } 

    @Override 
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { 
    } 
} 

i wdrożymy ten kliknie w działalności tak:

chatView.setLongClickable(true); 
     chatView.addOnItemTouchListener(
       new RecyclerViewItemClickListener(this, chatView, new RecyclerViewItemClickListener.OnItemClickListener() { 
        @Override public void onItemClick(View view, int position) { 

         //handleSingleClick(view, position); 

        } 
        @Override 
        public void onItemLongClick(View view, int position) 
        { 
         handleLongPress(position); 
        } 
       }) 
     ); 

kliknięć dla wiadomości działa, teraz chcę również obsługiwać userAvatar kliknięć z tego samego GestureDetection. Czy można wykryć, który układ elementów list został kliknięty od GestureDetector?

Innymi słowy, czy mogę uzyskać GestureDetecter klikniętego dziecka. W moim przypadku kliknięcie jest ustawione na cały element (awatar, wiadomość tekstową, obraz). Czy mogę wykryć, który element w tym elemencie został kliknięty (na przykład chcę kliknąć catch avatar).

Odpowiedz

-1

Kliknij trzeba obsłużyć w adaptera RecyclerView, odwiedź RecyclerView przykład podobny jak onItemClickListener z ListView

+0

dlaczego w dół !! – Sameer

0

Możesz spróbować tego kodu:

GestureDetector detector; 

następnie:

detector = new GestureDetector(MainActivity.this, MainActivity.this); 

    avatar.setOnTouchListener(new OnTouchListener() { 
     public boolean onTouch(View view, MotionEvent e) { 
      detector.onTouchEvent(e); 
      return false; 
     } 
    }); 
3

Obsługa kliknięcia w przejściówce Twój RecyclerView jak poniżej przykład:

private class BookmarkViewHolder extends RecyclerView.ViewHolder { 

     protected ImageView thumbnailIcon; 
     protected TextView postTitle; 
     protected TextView postViewCount; 

     public BookmarkViewHolder(View v) { 
      super(v); 

      thumbnailIcon = (ImageView) v.findViewById(R.id.thumbnailIcon); 
      postTitle = (TextView) v.findViewById(R.id.postTitleTV); 
      postViewCount = (TextView) v.findViewById(R.id.viewCountTV); 

      v.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) {             
       } 
      }); 

      thumbnailIcon.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) {             
       } 
      }); 

      postTitle.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) {             
       } 
      }); 


     } 
    } 
+0

Jak to działa, gdy próbujesz uzyskać pozycję listy w wywołaniu onClick ... to nie zadziała w metodzie viewHolder ... – Lion789

+0

użyj setTag(), aby ustawić pozycję pozycji w ten sposób ... ........................................ publiczny void onBindViewHolder (PostViewHolder postViewHolder, int i) { \t \t \t \t \t \t // znacznik ten zostanie wykorzystany po kliknięciu elementu ... \t \t \t postViewHolder.postTitle.setTag (I); \t \t \t postViewHolder.postTitle.setTag ("TITLE"); } – user320676

0

Możesz ustawić detektor do klasy adaptera. Oto kod:

klasa ViewHolder wewnątrz adaptera:

public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 

    TextView textViewFirstName; 
    ImageView imageViewProfile; 

    public MyViewHolder(View view) { 
     super(view); 
     textViewFirstName = (TextView) view.findViewById(R.id.txtName); 
     imageViewProfile = (ImageView) view.findViewById(R.id.imageViewProfile); 

//setOnClick 
     view.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View v) { 
    //check if the image you want to click should not invoke listener from activity/fragment 
     if (v.getId() != R.id.imageViewProfile) { 
      if (mItemClickListener != null) { 
       mItemClickListener.onItemClick(v, getPosition()); 
      } 
     } 
    } 
} 

Ustaw kliknięcie ImageView Adapter klasy onBindViewHolder:

@Override 
public void onBindViewHolder(MyViewHolder holder, final int position) { 

    holder.textViewFirstName.setText(mArrayListTypeDetials.get(position).getFirstname()); 
    //set imageView click here 
    holder.imageViewProfile.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      //ImageView clicked 
     } 
    }); 
} 

Tworzenie interfejsu wewnątrz klasy adaptera:

//interface for recyclerView item click 
public interface OnItemClickListener { 
    void onItemClick(View view, int position); 
} 

/* 
method to set listener to the adapter ViewHolder item 
*/ 
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) { 
    this.mItemClickListener = mItemClickListener; 
} 

Ustawianie interfejsu z Activity/Fragment:

mAdapter.setOnItemClickListener(new Adapter.OnItemClickListener() { 
     @Override 
     public void onItemClick(View view, int position) { 
      Intent intent = new Intent(getActivity(), ABC.class); 
      startActivity(intent); 
     } 
    }); 
0

based on this post.

//init listener 
rVDevicesList.addOnItemTouchListener(new RecyclerItemClickListener(getContext(), 
      rVDevicesList, 
      this, R.id.tv_wonderful_item_share, R.id.tv_wonderful_item_delete)); 




public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener { 

private OnItemClickListener mListener; 
private int[] extraIds; 
private Rect childRect = new Rect(); 

public interface OnItemClickListener { 
    void onItemClick(View view, int position); 

    void onLongItemClick(View view, int position); 
} 

private GestureDetector mGestureDetector; 

/** 
* 
* @param context 
* @param recyclerView 
* @param listener 
* @param ids: an alternative parameter 
*/ 
public RecyclerItemClickListener(Context context, 
           final RecyclerView recyclerView, 
           OnItemClickListener listener, final int... ids) { 
    mListener = listener; 
    extraIds = ids; 
    mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { 
     @Override 
     public boolean onSingleTapUp(MotionEvent e) { 
      return true; 
     } 

     @Override 
     public void onLongPress(MotionEvent e) { 
      View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); 
      if (child != null && mListener != null) { 
       mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child)); 
      } 
     } 
    }); 
} 

@Override 
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) { 
    final float x = e.getX(); 
    final float y = e.getY(); 
    Log.d("onInterceptTouchEvent", "onInterceptTouchEvent: " + x + " " + y); 
    View childView = view.findChildViewUnder(e.getX(), e.getY()); 
    if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { 
     final int position = view.getChildAdapterPosition(childView); 
     View target = getViewBy(childView, x, y, extraIds); 
     //if target is non-null,so you click the view. 
     mListener.onItemClick(target, position); 
     return true; 
    } 
    return false; 
} 

/** 
* find the view ,which view_rect contains the {x,y} in the window. 
* @param view: this view is item layout view,may be a viewGroup 
* @param x 
* @param y 
* @param ids 
* @return true: hit a view which id in ids. 
*/ 
private View getViewBy(View view, float x, float y, int... ids) { 
    if (ids == null || ids.length == 0 || !(view instanceof ViewGroup)) 
     return view; 
    for (int i : ids) { 
     View vChild = view.findViewById(i); 
     if (vChild == null) { 
      Log.d("onInterceptTouchEvent", "null"); 
     } else { 
      int xy[] = new int[2]; 
      vChild.getLocationOnScreen(xy); 
      childRect.left = xy[0]; 
      childRect.top = xy[1]; 
      childRect.right = xy[0] + vChild.getWidth(); 
      childRect.bottom = xy[1] + vChild.getHeight(); 
      boolean hit = childRect.contains((int) x, (int) y); 
      Log.d("onInterceptTouchEvent", "find view: " + hit); 
      if (hit) 
       return vChild; 
     } 
    } 
    return view; 
} 

@Override 
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { 

} 

@Override 
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { 
} 

}

+2

Powinieneś naprawdę wyjaśnić, dlaczego ten kod powinien zadziałać - możesz również dodawać komentarze w samym kodzie - w obecnej formie nie zawiera żadnego wyjaśnienia, które może pomóc reszcie społeczności w zrozumieniu tego, co zrobiłeś rozwiązać/odpowiedzieć na pytanie. – ishmaelMakitla

0

próbowałem ten sam sposób jak @ user320676, ale starałem się zakończyć z detektorem:

interface MultipleClickListener { 
     void onItemClickOne(int position, View v); 
     void onItemClickTwo(int position, View v); 
     void onItemClickThree(int position, View v); 
} 

następnie można użyć słuchacz w działaniu lub fragmencie.Tutaj możesz zobaczyć mój pełny Adapter:

public class MultipleClicksAdapter extends RecyclerView 
     .Adapter<MultipleClicksAdapter 
     .DataObjectHolder> { 

    private ArrayList<MultipleClickData> mDataset; 
    private static MultipleClickListener sClickListener; 

    static class DataObjectHolder extends RecyclerView.ViewHolder { 

     @BindView(R.id.multiple_clicks_one_textView) 
     TextView mOne; 
     @BindView(R.id.multiple_clicks_two_textView) 
     TextView mTwo; 
     @BindView(R.id.multiple_clicks_three_textView) 
     TextView mThree; 

     DataObjectHolder(View itemView) { 
      super(itemView); 

      ButterKnife.bind(this, itemView); 

      mOne.setOnClickListener((View v) -> 
        sClickListener.onItemClickOne(getAdapterPosition(), mOne)); 

      mTwo.setOnClickListener((View v) -> 
        sClickListener.onItemClickTwo(getAdapterPosition(), mTwo)); 

      mThree.setOnClickListener((View v) -> 
        sClickListener.onItemClickThree(getAdapterPosition(), mThree)); 
     } 

    } 

    void setOnItemClickListener(MultipleClickListener myClickListener) { 
     this.sClickListener = myClickListener; 
    } 

    MultipleClicksAdapter(ArrayList<MultipleClickData> myDataset) { 
     mDataset = myDataset; 
    } 

    @Override 
    public MultipleClicksAdapter.DataObjectHolder onCreateViewHolder(ViewGroup parent, 
                      int viewType) { 
     View view = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.multiple_clicks_list_item, parent, false); 

     MultipleClicksAdapter.DataObjectHolder dataObjectHolder = new MultipleClicksAdapter.DataObjectHolder(view); 
     return dataObjectHolder; 
    } 

    @Override 
    public void onBindViewHolder(MultipleClicksAdapter.DataObjectHolder holder, int position) { 
     holder.mOne.setText(mDataset.get(position).getmTitle()); 
     holder.mTwo.setText(mDataset.get(position).getmSubTitle()); 
     holder.mThree.setText(mDataset.get(position).getmThirdTitle()); 
    } 

    @Override 
    public int getItemCount() { 
     return mDataset.size(); 
    } 

    interface MultipleClickListener { 
     void onItemClickOne(int position, View v); 
     void onItemClickTwo(int position, View v); 
     void onItemClickThree(int position, View v); 
    } 

} 

Możesz również sprawdzić complete code in GitHub.

Powiązane problemy