2015-06-24 16 views
12

ho questo items.xmlRecyclerView Android: attr/selectableItemBackground non funziona su oggetti

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="horizontal" android:layout_width="match_parent" 
android:focusable="true" 
android:clickable="true" 
android:background="?android:attr/selectableItemBackground" 
android:layout_height="wrap_content"> 

<ImageView 
    android:layout_width="match_parent" 
    android:layout_height="60dp" 
    android:id="@+id/colorPreview" /> 


<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerInParent="true" 
    android:textAppearance="@android:style/TextAppearance.Large" 
    android:textColor="@android:color/white" 
    android:id="@+id/colorName" /> 

</RelativeLayout> 

Quando uso separatamente, il selectableItemBackground anima quando scatto la vista. Ma quando lo uso per gli elementi in un RecyclerView, l'effetto sul clic non si verifica più. Come posso risolvere questo?

PS: questo è l'ascoltatore sulla RecyclerView, se è rilevante:

public ColorListOnItemTouchListener(Context context, OnItemClickListener clickListener) { 
    mClickListener = clickListener; 
    mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { 
     @Override 
     public boolean onDown(MotionEvent e) { 
      return true; 
     } 

     @Override 
     public void onLongPress(MotionEvent e) { 
       if(childView != null && mClickListener != null) { 
        mClickListener.onItemLongPress(childView, index); 
       } 
     } 

     @Override 
     public boolean onSingleTapUp(MotionEvent e) { 
      if(childView != null && mClickListener != null) { 
       mClickListener.onItemClick(childView, index); 
      } 
      return true; 
     } 

     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
      return false; 
     } 
    }); 
} 

Grazie!

Edit:

public class ColorsCursorAdapter extends RecyclerView.Adapter<ColorsCursorAdapter.ViewHolder> { 

    private static final int layout = R.layout.color_item; 
    private Cursor mCursor; 

    public ColorsCursorAdapter(Cursor c) { 
     super(); 
     this.mCursor = c; 
    } 


    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false); 
     TextView name = (TextView) v.findViewById(R.id.colorName); 
     ImageView image = (ImageView) v.findViewById(R.id.colorPreview); 
     return new ViewHolder(v, name, image); 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     mCursor.moveToPosition(position); 
     int color = mCursor.getInt(mCursor.getColumnIndex(ColorItem.COLUMN_COLOR)); 
     holder.colorName.setText(Utils.getColorString(color)); 
     holder.colorPreview.setImageDrawable(new ColorDrawable(color)); 
    } 

    @Override 
    public int getItemCount() { 
     if(mCursor != null) { 
      return mCursor.getCount(); 
     } 
     return 0; 
    } 

    public void swapCursor(Cursor c) { 
     mCursor = c; 
     notifyDataSetChanged(); 
    } 

    public Cursor getCursor() { 
     return mCursor; 
    } 

    public static class ViewHolder extends RecyclerView.ViewHolder { 
     public TextView colorName; 
     public ImageView colorPreview; 

     public ViewHolder(View root, TextView colorName, ImageView colorPreview) { 
      super(root); 
      root.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        // 
       } 
      }); 
      this.colorName = colorName; 
      this.colorPreview = colorPreview; 
     } 
    } 
} 

e l'adattatore viene creato con:

colorList.setLayoutManager(new LinearLayoutManager(this)); 
    adapter = new ColorsCursorAdapter(null); 
    colorList.setAdapter(adapter); 
+0

Hai provato a impostare il listener Clic su holderView in adapter? – Hellboy

+0

L'ho fatto ... e non ha funzionato –

+0

ma hai impostato il listener su una vista che ha set selectablebackground? – Hellboy

risposta

4

Nella tua items.xml, impostare FrameLayout come il layout radice e impostare selectableItemBackground per FrameLayout. Funziona per me, ma non so perché.

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:foreground="?android:selectableItemBackground"> 

    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 
     <!-- your code --> 
    </RelativeLayout> 
</FrameLayout> 
+1

La ragione di ciò è che FrameLayout supporta l'attributo 'foreground' su livelli API inferiori a 23. Altre viste supportano solo l'avvio del livello API 23. – ubuntudroid

+0

Uso combinato con 'android: clickable =" true "' ha funzionato per me – Aba

12

Invece di impostarlo come sfondo, l'ho impostato come primo piano, funziona. Spero che sarebbe utile.

android:foreground="?attr/selectableItemBackground" 
+5

Non penso che funzionerà su API sotto il 23 però. –

+0

@VarvaraKalinina c'è un modo per farlo funzionare per livelli di API inferiori a 23? –

25

Qualcosa che non è stato menzionato in altre risposte: impostazione android:clickable="true" è necessaria al fine di rendere le animazioni funzionano quando non c'è OnClickListener attaccato alla vista.

0

Ho visto lo stesso comportamento. Da parte mia era legato al fatto che quando ho fatto clic su un elemento di una lista all'interno di un frammento e sostituito direttamente quel frammento con un altro, l'animazione non aveva tempo da mostrare. Non appena ho rimosso la sostituzione del frammento, ho potuto vedere l'animazione.

0
@Override 
    public boolean onSingleTapUp(MotionEvent e) { 
     if(childView != null && mClickListener != null) { 
      mClickListener.onItemClick(childView, index); 
     } 
     return true; 
    } 

Il ritorno falso potrebbe risolvere questo problema. Per quanto mi riguarda, ero sopraffatto da Touch sul mio pulsante e tornando vero alla fine. Tornando falsa abilitato il tocco di animazione per accadere da impostare:

android:background="?attr/selectableItemBackground" 
0

Nel mio caso il problema è stato causato da DividerItemDecoration. Appena me ne sono liberato, ha iniziato a funzionare. Suggerisco di mettere una riga alla fine del file xml per ogni articolo in RecyclerView, è molto più facile da personalizzare e non si verificheranno questi tipi di problemi.

Problemi correlati