23

如何将包含许多不同项目的视图统一变灰 - ImageViews、TextViews、背景图像。我必须单独将每件事情变灰吗?或者有没有办法对所有人应用相同的滤色器?

4

6 回答 6

23

除非其他人有更好的答案,否则我目前的方法是将每个项目分别变灰。

PorterDuffColorFilter greyFilter = new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
myLayout.getBackground().setColorFilter(greyFilter);
myImageView.setColorFilter(greyFilter);
myTextView.setTextColor(0xff777777);

对于更多或嵌套的子级,带有 instanceof 的循环可能是合适的,但我不需要它。

编辑:这个过滤器实际上不是灰色的,这里有一个更好的过滤器:Drawable => grayscale 可以以相同的方式使用。

于 2012-06-14T16:18:12.277 回答
15

通过如下定义自定义视图组很容易做到这一点:

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 的所有子视图都将显示为灰色。:-)

于 2013-04-04T05:27:28.287 回答
12

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()因为这会使应用程序崩溃。

于 2014-05-01T15:48:06.560 回答
7

这完全取决于您用于“灰色化”项目的方法。如果您通过调用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);
    }
}
于 2012-06-14T16:01:38.137 回答
0

我喜欢做的是创建一个与您尝试着色的视图重叠的视图,并将其背景设置为透明颜色。然后,您可以通过设置视图可见性来打开和关闭色调

<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);
于 2017-03-10T20:23:25.913 回答
0

如果您需要做的只是淡出或淡化视图颜色,则解决方案可以是

View.setAlpha(@FloatRange(from=0.0, to=1.0) float alpha)

这会改变整个视图的透明度

于 2021-08-18T21:18:58.913 回答