2014-10-29 27 views
19

Bir RecyclerView eyleminde işten çıkarma eylemi için bir tokatlamayı uygulamak çalışıyorum ancak ViewHolder'daki herhangi bir Görünümde bir OnClickListener ayarladığımda, o görünümdeki tüm OnTouch olaylarını geçersiz kılar.RecyclerView öğesinde tokatlamak ve OnClick olayları

OnClickListener öğesini bırakıp TouchListener uygulamasındaki tüm tıklamaları halledebilirim, ancak RecycleView öğesinin alt görünümünde birden fazla düğme varsa çok fazla kod olacak ve bu doğru bir şekilde görünmüyor. Benim RecyleView olarak

Ben Swipe (similar to this) dinleyicileri görevden ayarlıyorum:

setOnTouchListener(touchListener); 
    setOnScrollListener(touchListener.makeScrollListener()); 

Bu ListView çalışır, ancak olaylar OnTouchListner RecycleView OnClickListener bloklar halinde.

ViewHolder görünümü için düzen örneği.

@Override 
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
    View v = mInflater.inflate(R.layout.push_card_view_compat, viewGroup, false); 
    return new ViewHolder(v, onClickListener, onKeepListener); 
} 

ViewHolder: RecyclerView.Adapter içinde şişirilmesi

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:id="@+id/card_title" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:minHeight="72dp" 
android:descendantFocusability="blocksDescendants"> 

<ImageView 
    android:id="@+id/keep_icon" 
    android:layout_width="48dp" 
    android:layout_height="48dp" 
    android:layout_centerInParent="true" 
    android:src="@drawable/ic_received" /> 
I elde

public ViewHolder(final View itemView, 
        final OnViewHolderClickListener onClickListener, 
        final OnKeepListener onKeepListener) { 
    super(itemView); 
    keepButton = (ImageView) itemView.findViewById(R.id.keep_icon); 

    itemView.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     onItemClickListener.onClick(getPosition(), itemView); 
    } 
    }); 
    keepButton.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     onKeepListener.onClick(getPosition(), itemView); 
    } 
    }); 
} 
+1

kodunuzu sonra kod – pskink

+0

neden çok gönderebilir? –

+0

Kod ekledim. –

cevap

22

bu ViewHolder düğmelerin OnClickListener atama ve oluşturarak Dokunma olayları için bir arayüz.

Örnek proje GitHub üzerinde: https://github.com/brnunes/SwipeableRecyclerView. Benim durumumda

her öğe iki düğmeli bir CardView olduğunu ve CardView yılında dokunmatik olayları ve Button s algılamak istiyorum. CardView düzeni şu şekildedir:

public interface OnItemTouchListener { 
    public void onCardViewTap(View view, int position); 
    public void onButton1Click(View view, int position); 
    public void onButton2Click(View view, int position); 
} 

Ve ViewHolder yılında İstediğim nesnelere OnClickListeners atamak:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_margin="5dp" 
    android:clickable="true" 
    android:foreground="?android:attr/selectableItemBackground" 
    android:orientation="vertical" 
    card_view:cardCornerRadius="5dp"> 

    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <TextView 
      android:id="@+id/card_view_title" 
      android:layout_width="match_parent" 
      android:layout_height="50dp" 
      android:layout_alignParentTop="true" 
      android:layout_centerHorizontal="true" 
      android:gravity="center" 
      android:textColor="@android:color/black" 
      android:textSize="24sp" /> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_alignParentBottom="true" 
      android:layout_below="@id/card_view_title" 
      android:layout_centerHorizontal="true" 
      android:gravity="center"> 

      <Button 
       android:id="@+id/card_view_button1" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:text="Button1" /> 

      <Button 
       android:id="@+id/card_view_button2" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:text="Button2" /> 
     </LinearLayout> 
    </RelativeLayout> 

</android.support.v7.widget.CardView> 

Sonra Activity yılında, ben dokunma olaylarını almak için bir arabirim olarak ilan benim özel dinleyicisi dinlemek ve çağrı: özel örneğini, Nihayet

public class CardViewAdapter extends RecyclerView.Adapter<CardViewAdapter.ViewHolder> { 
    private List<String> cards; 
    private OnItemTouchListener onItemTouchListener; 

    public CardViewAdapter(List<String> cards, OnItemTouchListener onItemTouchListener) { 
     this.cards = cards; 
     this.onItemTouchListener = onItemTouchListener; 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
     View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_view_layout, viewGroup, false); 
     return new ViewHolder(v); 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder viewHolder, int i) { 
     viewHolder.title.setText(cards.get(i)); 
    } 

    @Override 
    public int getItemCount() { 
     return cards == null ? 0 : cards.size(); 
    } 

    public class ViewHolder extends RecyclerView.ViewHolder { 
     private TextView title; 
     private Button button1; 
     private Button button2; 

     public ViewHolder(View itemView) { 
      super(itemView); 
      title = (TextView) itemView.findViewById(R.id.card_view_title); 
      button1 = (Button) itemView.findViewById(R.id.card_view_button1); 
      button2 = (Button) itemView.findViewById(R.id.card_view_button2); 

      button1.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        onItemTouchListener.onButton1Click(v, getPosition()); 
       } 
      }); 

      button2.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        onItemTouchListener.onButton2Click(v, getPosition()); 
       } 
      }); 

      itemView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        onItemTouchListener.onCardViewTap(v, getPosition()); 
       } 
      }); 
     } 
    } 
} 

OnItemTouchListener ve CardViewAdapter yapıcı geçmek:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mItems = new ArrayList<>(30); 
    for (int i = 0; i < 30; i++) { 
     mItems.add(String.format("Card number %2d", i)); 
    } 

    OnItemTouchListener itemTouchListener = new OnItemTouchListener() { 
     @Override 
     public void onCardViewTap(View view, int position) { 
      Toast.makeText(MainActivity.this, "Tapped " + mItems.get(position), Toast.LENGTH_SHORT).show(); 
     } 

     @Override 
     public void onButton1Click(View view, int position) { 
      Toast.makeText(MainActivity.this, "Clicked Button1 in " + mItems.get(position), Toast.LENGTH_SHORT).show(); 
     } 

     @Override 
     public void onButton2Click(View view, int position) { 
      Toast.makeText(MainActivity.this, "Clicked Button2 in " + mItems.get(position), Toast.LENGTH_SHORT).show(); 
     } 
    }; 

    mAdapter = new CardViewAdapter(mItems, itemTouchListener); 

    mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); 

    mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    mRecyclerView.setAdapter(mAdapter); 

    // ... Assign the swipe listener 
} 
+0

Keşke bu kadar milyonlarca oy verebilseydim! Kaydırmam hala biraz yüklüydü, resimlerin yüklenmesi nedeniyle ... bu konuda herhangi bir tavsiye harika olurdu. : \ – marienke

+1

Çözüm, görüntüyü AsyncTask'ta eşzamansız olarak belleğe yüklemek ve sonra bunu ImageView'da göstermek. Bu makaleye http://developer.android.com/training/improving-layouts/smooth-scrolling.html#AsyncTask bakın. Bu yazı aynı zamanda async yüklemesi hakkında da konuşuyor. Örnekte, görüntüler internetten indirilir, ancak yerel olarak yüklüyorsanız daha da basittir: http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html – brnunes

+0

bunun için teşekkürler . – Tuss