Состояние цвета фона 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>
Ответы
Ответ 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>