Android CardView 背景颜色状态不被尊重
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25352930/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CardView background color states not being respected
提问by newfivefour
In brief:
简单来说:
How can we define color states of CardView's cardBackgroundColor property (in a ListView layout, in this case)?
我们如何定义 CardView 的 cardBackgroundColor 属性的颜色状态(在这种情况下,在 ListView 布局中)?
(I am using RC1 of Android L developer preview, on a phone with 4.4 installed, and "com.android.support:cardview-v7:21.0.0-rc1" in build.gradle)
(我使用的是 Android L 开发者预览版的 RC1,在安装了 4.4 的手机上,以及 build.gradle 中的“com.android.support:cardview-v7:21.0.0-rc1”)
Longer:
更长:
In CardView layout, we set the corner radius and background color of the CardView via cardCornerRadius and cardBackgroundColor.
在 CardView 布局中,我们通过 cardCornerRadius 和 cardBackgroundColor 设置 CardView 的角半径和背景颜色。
However, the background color doesn't repect selected states, i.e. if the list item is pressed, for example.
但是,背景颜色不代表选定状态,例如,如果按下列表项。
If, in the inner view of the CardView, you set a background colour, and associated states, which are respected, however, it will display over the corners you defined in the CardView.
但是,如果在 CardView 的内部视图中设置了背景颜色和相关状态,但是,它会显示在您在 CardView 中定义的角上。
So, how can we ensure the states in CardView's cardBackgroundColor are respected?
那么,我们如何确保 CardView 的 cardBackgroundColor 中的状态得到尊重?
Here's the color used for the cardBackgroundColor, colour_with_states.xml:
这是用于 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>
And the layout that uses the CardView:
以及使用 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>
回答by toobsco42
Though this is not ideal, since the edges are not rounded, you can add touch feedback to a CardView
like this :
虽然这并不理想,但由于边缘不是圆角,您可以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>
Adding the android:foreground
and android:clickable
attributes to the CardView
.
将android:foreground
和android:clickable
属性添加到CardView
.
Also this has a negative side effect in that the android:clickable
attribute overrides any clickListener, and therefore those clickListeners don't get triggered.
这也有一个负面影响,因为该android:clickable
属性会覆盖任何 clickListener,因此这些 clickListener 不会被触发。
Update
更新
I have some examples of CardView implementations
我有一些 CardView 实现的例子
Loop (https://github.com/lawloretienne/Loop) - https://github.com/lawloretienne/Loop/blob/master/app/src/main/res/layout/category_card.xml
循环 ( 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
QuickReturn ( https://github.com/lawloretienne/QuickReturn) - https://github.com/lawloretienne/QuickReturn/blob/master/sample/src/main/res/layout/activity_quick_return.xml
Update 2
更新 2
After more research I have come up with a good solution for CardViews on all API versions including pre-Lollipop.
经过更多研究,我为所有 API 版本(包括 Lollipop 之前)上的 CardViews 提出了一个很好的解决方案。
https://medium.com/@etiennelawlor/layout-tips-for-pre-and-post-lollipop-bcb2e4cdd6b2#.9h0v1gmaw
https://medium.com/@etiennelawlor/layout-tips-for-pre-and-post-lollipop-bcb2e4cdd6b2#.9h0v1gmaw
回答by Anthony Chuinard
Sometimes, you may want the CardView
to have visual touch feedback. The android:foreground="?android:attr/selectableItemBackground"
solution is perfect for this.
有时,您可能希望CardView
具有视觉触摸反馈。该android:foreground="?android:attr/selectableItemBackground"
解决方案是为这个完美的。
However, you may consider using drawSelectorOnTop(true)
with your ListView. This will require no change on your CardView
at all.
但是,您可以考虑drawSelectorOnTop(true)
与您的 ListView 一起使用。这根本不需要改变你CardView
的。
Let me know if further clarification is needed.
让我知道是否需要进一步澄清。
回答by Loyea
Here's my way to solve your problem.
这是我解决您问题的方法。
First, create a custom class named CustomCardView
extends CardView
首先,创建一个名为CustomCardView
extends的自定义类CardView
Then override the drawableStateChanged()
method, change the card background color by call setCardBackgroundColor()
method when card's press status changed.
然后重写该drawableStateChanged()
方法,setCardBackgroundColor()
当卡片的按下状态发生变化时,通过调用方法更改卡片背景颜色。
Last, replace the CardView with this CustomCardView in you layout file.
最后,用布局文件中的这个 CustomCardView 替换 CardView。
the only one disadvantage of this solution is cardview can't display ripple press effect on Android 5.0 and above.
该解决方案唯一的缺点是cardview在Android 5.0及更高版本上无法显示波纹按压效果。
here's my code:
这是我的代码:
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));
}
}
}
}
回答by weiy
One workaround which I used was to do the UI changes programmatically by overriding the View.OnTouchListener OnTouch() event handler within my custom ViewHolder.
我使用的一种解决方法是通过覆盖自定义 ViewHolder 中的 View.OnTouchListener OnTouch() 事件处理程序以编程方式更改 UI。
@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;
}
回答by Prashant Maheshwari Andro
**Just add there lines inside card view **
**只需在卡片视图中添加行**
android:clickable="true"
android:focusableInTouchMode="true"
android:foreground="?android:attr/selectableItemBackground"
回答by Prashant Maheshwari Andro
If you look at the definition of carBackgroundColor property, at least in android support library it is:
如果您查看 carBackgroundColor 属性的定义,至少在 android 支持库中它是:
<resources>
<declare-styleable name="CardView">
<!-- Background color for CardView. -->
<attr name="cardBackgroundColor" format="color" />
</declare-styleable>
</resource>
Here it says it takes only color for cardBackgroundValue. I guess this means selector is not respected but falls through to the default value ie. color at the bottom of your selector.
这里说它只需要 cardBackgroundValue 的颜色。我想这意味着选择器不受尊重,但会落入默认值,即。选择器底部的颜色。
回答by Piash Sarker
Use android:foreground
instead of android:background
in your <CardView/>
. below are sample code of a CardView .
使用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>
回答by Mohammad Reza Khahani
You can use color state in code and it work perfectly.
您可以在代码中使用颜色状态,它工作得很好。
cardView.setCardBackgroundColor(context.getColorStateList(R.color.card_view_selectable))
in color > card_view_selectable.xml
颜色 > card_view_selectable.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#4fc3f7" android:state_activated="true" />
<item android:color="#fff" />
</selector>
Then use isActivated cause background color changed to state_activated or default.
然后使用 isActivated 导致背景颜色更改为 state_activated 或默认值。
cardView.isActivated = true // or false
回答by Dr. Hasan Hashem
I used a rectangle shape with the same corner radius as the cardview. And then used the xml drawable as a background for the inner view of the cardview. The background does not display over cardview corner, though i still get a small padding between the card and its inner view.
我使用了一个与 cardview 具有相同圆角半径的矩形形状。然后使用 xml drawable 作为 cardview 内部视图的背景。背景不会显示在 cardview 角落,但我仍然在卡片和它的内部视图之间有一个小填充。