Android 如何将颜色过滤器应用于所有孩子的视图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11036835/
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
How to apply a color filter to a view with all children
提问by Ixx
How do I grey out a view uniformly which contains many different items - ImageViews, TextViews, background image. Do I have to grey out each thing individually? Or is there a way to apply the same color filter to all?
如何使包含许多不同项目的视图统一变灰 - ImageViews、TextViews、背景图像。我是否必须单独将每件事变灰?或者有没有办法对所有人应用相同的滤色器?
回答by Ixx
Unless somebody else has a better answer, my current method is greying out each item separatedly.
除非其他人有更好的答案,否则我目前的方法是分别将每个项目变灰。
PorterDuffColorFilter greyFilter = new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
myLayout.getBackground().setColorFilter(greyFilter);
myImageView.setColorFilter(greyFilter);
myTextView.setTextColor(0xff777777);
For more or nested children probably a loop with instanceof would be suitable but I don't need it.
对于更多或嵌套的孩子,可能适合使用 instanceof 的循环,但我不需要它。
Edit: This filter isn't actually grey, a better filter is here: Drawable => grayscaleWhich can be used in the same way.
编辑:这个过滤器实际上不是灰色的,更好的过滤器在这里:Drawable => grayscale可以以相同的方式使用。
回答by Sam Lu
It's easy to do that by defining a custom view group as follows:
通过如下定义自定义视图组很容易做到这一点:
public class MyViewContainer extends XXXLayout {
//XXLayout could be LinearLayout, RelativeLayout or others
private Paint m_paint;
//define constructors here and call _Init() at the end of constructor function
private void
_Init()
{
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
m_paint = new Paint();
m_paint.setColorFilter(new ColorMatrixColorFilter(cm));
}
@Override protected void
dispatchDraw(Canvas canvas)
{
canvas.saveLayer(null, m_paint, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
canvas.restore();
}
}
All children views of MyViewContainer will be shown in grey. :-)
MyViewContainer 的所有子视图都将显示为灰色。:-)
回答by Learn OpenGL ES
Sam Lu's answer is a good start, but I had performance problems and decided to switch to hardware layers. With hardware layers, you can do it like this:
Sam Lu 的回答是一个好的开始,但我遇到了性能问题并决定切换到硬件层。使用硬件层,您可以这样做:
private final Paint grayscalePaint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
grayscalePaint.setColorFilter(new ColorMatrixColorFilter(cm));
public void setGrayedOut(boolean grayedOut) {
if (grayedOut) {
setLayerType(View.LAYER_TYPE_HARDWARE, grayscalePaint);
} else {
setLayerType(View.LAYER_TYPE_NONE, null);
}
}
Be careful not to do the layers in dispatchDraw()
itself as that will crash the app.
小心不要自己做图层,dispatchDraw()
因为这会导致应用程序崩溃。
回答by Devunwired
It depends entirely on the method you are using to "gray out" items. If you are doing so by calling setEnabled(false)
on the parent ViewGroup
, by default state flags (like disabled) do not trickle down to the child views. However, there are two simple ways you can customize this:
这完全取决于您用来“变灰”项目的方法。如果您通过调用setEnabled(false)
parent来这样做ViewGroup
,默认情况下状态标志(如禁用)不会渗透到子视图。但是,您可以通过两种简单的方法对其进行自定义:
One option is to add the attributeandroid:duplicateParentState="true"
to each child view in your XML. This will tell the children to get their state flags from the parent. This will mirror ALL flags however, including pressed, checked, etc...not just enabled.
一种选择是将属性添加android:duplicateParentState="true"
到 XML 中的每个子视图。这将告诉孩子们从父母那里获取他们的状态标志。然而,这将反映所有标志,包括按下、选中等......不仅仅是启用。
Another option is to create a custom subclassof your ViewGroup
and override setEnabled()
to call all the child views as well, i.e.
另一种选择是创建一个自定义子类,您的ViewGroup
并覆盖setEnabled()
调用所有孩子的意见为好,即
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
for(int i=0; i < getChildCount(); i++) {
getChildAt(i).setEnabled(enabled);
}
}
回答by Anthony Olds
What I like to do is create a view which overlaps the view you are trying to tint and set its background to a transparent color. Then you can turn the tint on and off by setting that views visibility
我喜欢做的是创建一个视图,该视图与您尝试着色的视图重叠并将其背景设置为透明颜色。然后您可以通过设置视图可见性来打开和关闭色调
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewYouWantToTint
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<View
android:id="@+id/disabled_tint_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/darkTint"
android:visibility="invisible"/>
</FrameLayout>
Then in your controller:
然后在您的控制器中:
m_DisabledBlackTintOverlay = (View) view.findViewById(R.id.login_disabled_black_tint_overlay);
m_DisabledBlackTintOverlay.setVisibility(View.VISIBLE);