如何将包含许多不同项目的视图统一变灰 - ImageViews、TextViews、背景图像。我必须单独将每件事情变灰吗?或者有没有办法对所有人应用相同的滤色器?
6 回答
除非其他人有更好的答案,否则我目前的方法是将每个项目分别变灰。
PorterDuffColorFilter greyFilter = new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
myLayout.getBackground().setColorFilter(greyFilter);
myImageView.setColorFilter(greyFilter);
myTextView.setTextColor(0xff777777);
对于更多或嵌套的子级,带有 instanceof 的循环可能是合适的,但我不需要它。
编辑:这个过滤器实际上不是灰色的,这里有一个更好的过滤器:Drawable => grayscale 可以以相同的方式使用。
通过如下定义自定义视图组很容易做到这一点:
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();
}
}
MyViewContainer 的所有子视图都将显示为灰色。:-)
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);
}
}
注意不要自己做图层,dispatchDraw()
因为这会使应用程序崩溃。
这完全取决于您用于“灰色化”项目的方法。如果您通过调用setEnabled(false)
parent来执行此操作ViewGroup
,则默认状态标志(如禁用)不会滴入子视图。但是,有两种简单的方法可以自定义它:
一种选择是将属性添加 android:duplicateParentState="true"
到 XML 中的每个子视图。这将告诉孩子们从父母那里得到他们的州旗。然而,这将反映所有标志,包括按下、选中等......不仅仅是启用。
另一种选择是创建您的自定义子类ViewGroup
并覆盖setEnabled()
以调用所有子视图,即
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
for(int i=0; i < getChildCount(); i++) {
getChildAt(i).setEnabled(enabled);
}
}
我喜欢做的是创建一个与您尝试着色的视图重叠的视图,并将其背景设置为透明颜色。然后,您可以通过设置视图可见性来打开和关闭色调
<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>
然后在你的控制器中:
m_DisabledBlackTintOverlay = (View) view.findViewById(R.id.login_disabled_black_tint_overlay);
m_DisabledBlackTintOverlay.setVisibility(View.VISIBLE);
如果您需要做的只是淡出或淡化视图颜色,则解决方案可以是
View.setAlpha(@FloatRange(from=0.0, to=1.0) float alpha)
这会改变整个视图的透明度