android - recyclerview - recycler view cardview
No se respeta el color de fondo de CardView (8)
** Solo agregue líneas dentro de la vista de tarjeta **
android:clickable="true"
android:focusableInTouchMode="true"
android:foreground="?android:attr/selectableItemBackground"
En breve:
¿Cómo podemos definir los estados de color de la propiedad cardBackgroundColor de CardView (en un diseño ListView, en este caso)?
(Estoy utilizando RC1 de la vista previa del desarrollador de Android L, en un teléfono con 4.4 instalado, y "com.android.support:cardview-v7:21.0.0-rc1" en build.gradle)
Más:
En el diseño de CardView, establecemos el radio de la esquina y el color de fondo de CardView a través de cardCornerRadius y cardBackgroundColor.
Sin embargo, el color de fondo no refleja los estados seleccionados, es decir, si se presiona el elemento de la lista, por ejemplo.
Si, en la vista interna de CardView, establece un color de fondo y los estados asociados, que se respetan, sin embargo, se mostrará en las esquinas que definió en CardView.
Entonces, ¿cómo podemos garantizar que se respeten los estados de cardView''s cardBackgroundColor?
Aquí está el color utilizado para el cardBackgroundColor, colour_with_states.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:color="@android:color/holo_green_dark" />
<item android:state_focused="true" android:state_enabled="false" android:color="@android:color/holo_green_dark" />
<item android:state_focused="true" android:state_pressed="true" android:color="@android:color/holo_green_dark" />
<item android:state_focused="false" android:state_pressed="true" android:color="@android:color/holo_green_dark" />
<item android:state_focused="true" android:color="@android:color/holo_green_dark" />
<!-- Only this below is seen in the cardview dispaly -->
<item android:color="@android:color/holo_blue_bright" />
</selector>
Y el diseño que utiliza el CardView:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardview="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
cardview:cardCornerRadius="10dp"
cardview:cardBackgroundColor="@color/colour_with_states"
>
<!-- If we set a background color below, it will overwrite our radius defined above -->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:text="Lorem ipsum"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem"
android:background="@null"
android:gravity="center_vertical"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:paddingStart="8dip"
android:paddingEnd="8dip"
/>
</android.support.v7.widget.CardView>
A veces, es posible que desee que el CardView
tenga retroalimentación táctil visual. La solución de android:foreground="?android:attr/selectableItemBackground"
es perfecta para esto.
Sin embargo, puede considerar usar drawSelectorOnTop(true)
con su ListView. Esto no requerirá ningún cambio en su CardView
en absoluto.
Déjame saber si se necesita más aclaración.
Aquí está mi manera de resolver su problema.
Primero, crea una clase personalizada llamada CustomCardView
extiende CardView
Luego, anule el método setCardBackgroundColor()
, cambie el color de fondo de la tarjeta con el método de setCardBackgroundColor()
cuando cambie el estado de la prensa de la tarjeta.
Por último, reemplace el CardView con este CustomCardView en su archivo de diseño.
La única desventaja de esta solución es que Cardview no puede mostrar un efecto de presión de rizo en Android 5.0 y superior.
Aquí está mi código:
public class CustomCardView extends CardView {
public CustomCardView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public CustomCardView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomCardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
if (isPressed()) {
this.setCardBackgroundColor(getContext().getResources().getColor(R.color.card_view_pressed));
} else {
this.setCardBackgroundColor(getContext().getResources().getColor(R.color.card_view_normal));
}
}
}
Aunque esto no es lo ideal, ya que los bordes no están redondeados, puede agregar retroalimentación táctil a un CardView
como este:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="4dp"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground">
//Nested View ...
</android.support.v7.widget.CardView>
Agregando los atributos de android:foreground
y android:clickable
CardView
el CardView
.
Además, esto tiene un efecto secundario negativo en el hecho de que el atributo android:clickable
anula cualquier clickListener, y por lo tanto, esos clickListeners no se activan.
Actualizar
Tengo algunos ejemplos de implementaciones de CardView.
Loop ( https://github.com/lawloretienne/Loop ) - https://github.com/lawloretienne/Loop/blob/master/app/src/main/res/layout/category_card.xml
QuickReturn ( https://github.com/lawloretienne/QuickReturn ) - https://github.com/lawloretienne/QuickReturn/blob/master/sample/src/main/res/layout/activity_quick_return.xml
Actualización 2
Después de más investigaciones, he encontrado una buena solución para las vistas de tarjeta en todas las versiones de API, incluida la pre-Lollipop.
https://medium.com/@etiennelawlor/layout-tips-for-pre-and-post-lollipop-bcb2e4cdd6b2#.9h0v1gmaw
Si nos fijamos en la definición de propiedad carBackgroundColor, al menos en la biblioteca de soporte de Android es:
<resources>
<declare-styleable name="CardView">
<!-- Background color for CardView. -->
<attr name="cardBackgroundColor" format="color" />
</declare-styleable>
</resource>
Aquí dice que solo toma color para cardBackgroundValue. Supongo que esto significa que el selector no se respeta, pero cae al valor predeterminado, es decir. Color en la parte inferior de su selector.
Una solución que utilicé fue hacer los cambios de la interfaz de usuario mediante programación anulando el controlador de eventos View.OnTouchListener OnTouch () dentro de mi ViewHolder personalizado.
@Override
public boolean onTouch (View v, MotionEvent event)
{
int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN)
{
mCardView.setCardBackgroundColor(STATE_PRESSED_COLOR);
}
else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL)
{
mCardView.setCardBackgroundColor(DEFAULT_COLOR);
}
return false;
}
Usé una forma de rectángulo con el mismo radio de esquina que la vista de tarjeta. Y luego usó el dibujo XML como fondo para la vista interior de la vista de tarjeta. El fondo no se muestra en la esquina de la vista de tarjeta, aunque todavía tengo un pequeño relleno entre la tarjeta y su vista interior.
Use android:foreground
lugar de android:background
en su <CardView/>
. A continuación se muestra el código de ejemplo de un CardView.
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="2dp"
app:cardElevation="2dp">
// others view component
</android.support.v7.widget.CardView>