Подтвердить что ты не робот

Состояние цвета фона CardView не соблюдается

Вкратце:

Как мы можем определить состояния цвета свойства CardView cardBackgroundColor (в данном случае в макете ListView)?

(Я использую RC1 предварительного просмотра разработчика Android L на телефоне с установленным 4.4 и "com.android.support:cardview-v7:21.0.0-rc1" в build.gradle)

дольше:

В макете CardView мы устанавливаем радиус угла и цвет фона CardView через cardCornerRadius и cardBackgroundColor.

Однако цвет фона не отражает выбранные состояния, например, если элемент списка нажат, например.

Если во внутреннем виде CardView вы задаете цвет фона и ассоциированные состояния, которые соблюдаются, однако, он будет отображаться по углам, определенным вами в CardView.

Итак, как мы можем обеспечить соответствие состояний в CardView cardBackgroundColor?

Здесь цвет, используемый для 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>

И макет, который использует 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>
4b9b3361

Ответ 1

Хотя это не идеально, поскольку ребра не закруглены, вы можете добавить обратную связь касания к CardView следующим образом:

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

Добавление атрибутов android:foreground и android:clickable в CardView.

Также это имеет отрицательный побочный эффект в том, что атрибут android:clickable переопределяет любой clickListener, и поэтому эти функции clickListeners не запускаются.

Update

У меня есть несколько примеров реализаций 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

Обновление 2

После дополнительных исследований я придумал хорошее решение для CardViews во всех версиях API, включая pre-Lollipop.

https://medium.com/@etiennelawlor/layout-tips-for-pre-and-post-lollipop-bcb2e4cdd6b2#.9h0v1gmaw

Ответ 2

Иногда вы можете иметь CardView визуальную обратную связь. Решение android:foreground="?android:attr/selectableItemBackground" идеально подходит для этого.

Однако вы можете использовать drawSelectorOnTop(true) в своем ListView. Это не потребует изменений на вашем CardView вообще.

Сообщите мне, если потребуется дополнительное разъяснение.

Ответ 3

Вот мой способ решить вашу проблему.

Сначала создайте пользовательский класс с именем CustomCardView extends CardView

Затем переопределите метод drawableStateChanged(), измените цвет фона карты методом вызова setCardBackgroundColor(), когда изменилось состояние нажатия карты.

Наконец, замените CardView на этот CustomCardView в вашем файле макета.

Единственным недостатком этого решения является то, что cardview не может отображать эффект пульсации на Android 5.0 и выше.

здесь мой код:

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

}

Ответ 4

Одним из способов, которые я использовал, было внесение программных изменений в пользовательский интерфейс путем переопределения обработчика событий View.OnTouchListener OnTouch() в моем пользовательском ViewHolder.

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

Ответ 5

** Просто добавьте туда строки внутри вида карты **

    android:clickable="true"
    android:focusableInTouchMode="true"
    android:foreground="?android:attr/selectableItemBackground"

Ответ 6

Я использовал прямоугольную форму с тем же угловым радиусом, что и карта. А затем использовал xml drawable в качестве фона для внутреннего вида карты. Фон не отображается в углу карты, хотя я все еще получаю небольшое дополнение между картой и ее внутренним видом.

введите описание изображения здесь

Ответ 7

Если вы посмотрите на определение свойства carBackgroundColor, по крайней мере, в библиотеке поддержки android:

<resources>
    <declare-styleable name="CardView">
        <!-- Background color for CardView. -->
        <attr name="cardBackgroundColor" format="color" />
    </declare-styleable>
</resource>

Здесь говорится, что для cardBackgroundValue требуется только цвет. Я предполагаю, что это означает, что селектор не соблюдается, но падает до значения по умолчанию, т.е. цвет в нижней части селектора.

Ответ 8

Используйте android:foreground вместо android:background в <CardView/>. ниже приведен пример кода 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>