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



вкратце:



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



(Я использую RC1 из Android L developer preview, на телефоне с установленным 4.4 и " com.андроид.поддержка: cardview-v7: 21.0.0-rc1 " в сборке.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>
590   8  

8 ответов:

хотя это не идеально, так как края не закруглены, вы можете добавить сенсорную обратную связь к 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 не срабатывают.

обновление

у меня есть несколько примеров реализации CardView

петли (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

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

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

Дайте мне знать, если необходимы дополнительные разъяснения.

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

во-первых, создайте пользовательский класс с именем 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));
    }
}

}

один обходной путь, который я использовал, состоял в том, чтобы сделать изменения пользовательского интерфейса программно, переопределив представление.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;
}

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

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

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

enter image description here

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

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

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

использовать 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>

Comments

    Ничего не найдено.