2014-10-29 22 views
19

में स्वाइप और ऑनक्लिक घटनाएं मैं रीसाइक्लिंग व्यू में कार्रवाई को खारिज करने के लिए एक स्वाइप लागू करने की कोशिश कर रहा हूं, लेकिन जब मैं एक व्यूहोल्डर में किसी भी दृश्य पर ऑनक्लिक लिस्टनर सेट करता हूं तो यह उस दृश्य पर सभी ऑन टच ईवेंट ओवरराइड करता है।रीसाइक्लर व्यू

मैं ऑनक्लिक लिस्टनर को छोड़ सकता हूं और टच लिस्टनर में सभी क्लिकों को संभाल सकता हूं लेकिन यदि मेरे पास रीसायकल व्यू के एक बच्चे के दृश्य में एकाधिक बटन हैं, तो यह बहुत सारे कोड होंगे और यह सही तरीके से नहीं दिखता है।

मेरी RecyleView में मैं स्वाइप श्रोताओं को खारिज करने (similar to this) सेट कर रहा हूं:

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

यह ListView में काम करता है, लेकिन घटनाओं OnTouchListner RecycleView OnClickListener ब्लॉकों में।

व्यूहोल्डर दृश्य के लिए लेआउट का उदाहरण।

<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" /> 

RecyclerView.Adapter में बढ़ाना:

@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:

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

अपने कोड पोस्ट तो कोड की – pskink

+0

क्यों बहुत सारे? –

+0

मैंने कोड जोड़ा है। –

उत्तर

22

मैं हासिल की है कि ViewHolder में बटन के लिए OnClickListener बताए, और बनाने के द्वारा स्पर्श घटनाओं के लिए एक इंटरफ़ेस।

नमूना प्रोजेक्ट गिटहब पर है: https://github.com/brnunes/SwipeableRecyclerView

मेरे मामले में प्रत्येक आइटम दो बटन के साथ एक CardView है, और मैं CardView में स्पर्श घटनाओं और Button रों पता लगाने के लिए चाहते हैं। CardView लेआउट इस तरह दिखता है:

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

और ViewHolder में मैं वस्तुओं है कि मैं चाहता हूँ करने के लिए OnClickListeners आवंटित:

<?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> 

फिर Activity में, मैं स्पर्श इवेंट प्राप्त करने के लिए एक अंतरफलक घोषित सुनने के लिए, और फोन अपने कस्टम श्रोता: अंत में

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 और यह CardViewAdapter निर्माता को पारित:

@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

मेरी इच्छा है कि मैं इसे दस लाख बार वोट दूंगा! छवियों को लोड करने के कारण, मेरी स्क्रॉलिंग अभी भी थोड़ी सी परेशान है ... उस पर कोई सलाह बहुत अच्छी होगी। : \ – marienke

+1

समाधान छवि को असीमित रूप से एक AsyncTask में लोड करना है, और फिर इसे ImageView में दिखाएं। इस आलेख को http://developer.android.com/training/improving-layouts/smooth-scrolling.html#AsyncTask देखें। यह पोस्ट एसिंक लोडिंग के बारे में भी बात करता है। उदाहरण में छवियों को इंटरनेट से डाउनलोड किया जाता है, लेकिन यदि आप उन्हें स्थानीय रूप से लोड कर रहे हैं तो यह भी आसान है: http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html – brnunes

+0

इसके लिए धन्यवाद । – Tuss

संबंधित मुद्दे