2015-06-24 11 views
12

Ich habe diese items.xmlRecyclerView android: attr/selectableItemBackground funktioniert nicht auf Artikel

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

Wenn ich es separat verwenden, der selectableItemBackground beseelt, wenn ich die Ansicht klicken. Aber wenn ich es für die Elemente in einem RecyclerView verwende, passiert der Effekt beim Klicken nicht mehr. Wie kann ich das beheben?

PS: Dies ist der Hörer auf der RecyclerView ist, wenn es relevant:

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

Thank you!

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

Und der Adapter erstellt mit:

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

Haben Sie versucht, OnClick Listener auf HolderView im Adapter zu setzen? – Hellboy

+0

Ich habe ... und es hat nicht funktioniert –

+0

aber haben Sie Listener auf eine Ansicht, die selectivebackground gesetzt hat gesetzt? – Hellboy

Antwort

4

In Ihrem items.xml, als Root-Layout festgelegt FrameLayout und setzen selectableItemBackground für FrameLayout. Es funktioniert für mich, aber ich weiß nicht warum.

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

Der Grund dafür ist, dass FrameLayout das 'Vordergrund'-Attribut auf niedrigeren API-Ebenen als 23 unterstützt. Andere Ansichten unterstützen nur API-Level 23. – ubuntudroid

+0

Verwenden Sie dies in Kombination mit 'android: clickable =" true "' funktionierte für mich – Aba

12

Anstatt es als Hintergrund einzustellen, stelle ich es als Vordergrund, es funktioniert. Ich hoffe es wäre hilfreich.

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

Ich glaube nicht, dass es auf API unterhalb von 23 obwohl arbeiten wird. –

+0

@VarvaraKalinina gibt es eine Möglichkeit, es für API-Ebenen unter 23 arbeiten zu lassen? –

25

Etwas, das nicht in anderen Antworten erwähnt wurde: Einstellung android:clickable="true" ist erforderlich, um die Animationen zu machen arbeiten, wenn es keine OnClickListener die Ansicht angebracht ist.

0

Ich habe das gleiche Verhalten gesehen. Auf meiner Seite war es mit der Tatsache verbunden, dass, als ich ein Listenelement innerhalb eines Fragments angeklickt und dieses Fragment direkt durch ein anderes ersetzt hatte, hatte die Animation keine Zeit, um gezeigt zu werden. Sobald ich den Fragmentersatz entfernt hatte, konnte ich die Animation sehen.

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

Rückgabe false könnte dieses Problem beheben. Für mich war ich auf Touch auf meinem Knopf und am Ende wahr. False zurückgibt die Touch-Animation aktiviert passiert von der Einstellung:

android:background="?attr/selectableItemBackground" 
0

In meinem Fall ist das Problem von DividerItemDecoration verursacht wurde. Sobald ich das los war, fing es an zu arbeiten. Ich schlage vor, eine Zeile am Ende der xml Datei für jeden Artikel in RecyclerView zu setzen, es ist viel einfacher zu anpassen und Sie werden nicht in diese Art von Problemen laufen.

Verwandte Themen