无法将colorFilter应用于文本选择控制柄

时间:2015-02-01 14:10:39

标签: android material-design nine-patch android-bitmap

我正在尝试将素材选择句柄带到我的应用中。我从SDK获得了中间/右/左手柄(位图)和文本光标(9-patch)的drawables,并设置:

<item name="android:textSelectHandleLeft">@drawable/text_select_handle_left_mtrl_alpha</item>
<item name="android:textSelectHandleRight">@drawable/text_select_handle_right_mtrl_alpha</item>
<item name="android:textSelectHandle">@drawable/text_select_handle_middle_mtrl_alpha</item>
<item name="android:textCursorDrawable">@drawable/text_cursor_mtrl_alpha</item>

它按预期工作。但是,在Lollipop中,这些drawables使用android:tint属性在XML中使用特定颜色着色,我无法在API&lt; 21上使用该属性。所以我试图在运行时设置一个颜色过滤器。

enter image description here

  • 文字光标没有着色。我想这可能是因为它是9补丁。如何在运行时过滤9-patch drawable?我尝试了所有PorterDuff.Mode s。

  • 右/左手柄为黑色,中间手柄为白色。

是的,根据我的意愿,它们中没有它们是绿色的。为什么呢?

正如您在上面所看到的,我在编辑文本下面设置了四个ImageView,然后它们会被着色。

   private void setUpTextCursors() {
        Drawable left = getResources().getDrawable(R.drawable.text_select_handle_left_mtrl_alpha);
        Drawable right = getResources().getDrawable(R.drawable.text_select_handle_right_mtrl_alpha);
        Drawable middle = getResources().getDrawable(R.drawable.text_select_handle_middle_mtrl_alpha);
        Drawable cursor = getResources().getDrawable(R.drawable.text_cursor_mtrl_alpha);
        ColorFilter cf = new PorterDuffColorFilter(mGreenColor, PorterDuff.Mode.SRC_IN);

        /**
        * tint my ImageViews, but no effect on edit text handles
        */
        left.setColorFilter(cf); 
        right.setColorFilter(cf);
        middle.setColorFilter(cf);

        /**
        * no effect whatsoever
        */
        cursor.setColorFilter(cf);
   }

在这里看起来我们都有一个9补丁着色问题 - 因为即使在测试ImageViews上过滤器也失败了 - 以及与文本选择管理器没有考虑任何应用过滤器这一事实相关的问题。

相关的相关源代码来自TextView classEditor隐藏的helper class,我以某种方式找到了它。花了一些时间,但仍然无法说明我的过滤器被忽略的原因。


要@pskink:让cursor成为已过滤的drawable,我可以:

<ImageView
    android:id="@id/1"
    android:src="@drawable/cursor_drawable" />

<ImageView 
    android:id="@id/2" />

第一个没有被染色,但如果我打电话给imageView2.setBackground(cursor),那么它就会被染色。 如果我有

<item name="android:textSelectHandle">@drawable/cursor_drawable</item>

这会影响编辑选择(因为我会覆盖默认光标),但它不会再次着色。

2 个答案:

答案 0 :(得分:2)

您需要覆盖您的活动使用的默认资源:

// your activity source file
Resources res;

@Override
public Resources getResources() {
    if (res == null) {
        res = new TintResources(super.getResources());
    }
    return res;
}

自定义Resources类将覆盖getDrawable()方法,因此您可以拦截创建Drawable并设置颜色过滤器,例如:

class TintResources extends Resources {

    public TintResources(Resources resources) {
        super(resources.getAssets(), resources.getDisplayMetrics(), resources.getConfiguration());
    }

    @Override
    public Drawable getDrawable(int id) throws NotFoundException {
        Drawable d = super.getDrawable(id);
        if (id == R.drawable.text_cursor_material) {
            // setup @drawable/text_cursor_material
            d.setColorFilter(0xff00aa00, PorterDuff.Mode.SRC_IN);
        }
        return d;
    }
}

与设置其他Drawables的方式相同(@ drawable / text_select_handle _ * _ material),请注意,由于EditText没有用于访问这些Drawables的getter方法,因此需要这不是直接的方式

答案 1 :(得分:0)

这只是一个部分答案,我们也可以认为它非常糟糕,因为它是一种解决方法。我能够通过指向XML文件而不是原始png文件来加载edittext(或任何其他选择内容)中的句柄(即BitmapDrawables)。即我设置:

<item name="android:textSelectHandleLeft">@drawable/text_select_handle_left_material</item>
<item name="android:textSelectHandleRight">@drawable/text_select_handle_right_material</item>
<item name="android:textSelectHandle">@drawable/text_select_handle_middle_material</item>
<item name="android:textCursorDrawable">@drawable/text_cursor_material</item>

这些是xml drawables,如:

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/text_select_handle_left_mtrl_alpha" />

<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/text_cursor_mtrl_alpha" />

如果我过滤这些drawable,我发现它们在选择中的视图中着色 。所以我改变了我的方法:

private void setUpTextCursors() {
    ColorFilter cf = new PorterDuffColorFilter(mColorControlActivated, PorterDuff.Mode.SRC_IN);
    BitmapDrawable left = (BitmapDrawable) getResources().getDrawable(R.drawable.text_select_handle_left_material);
    BitmapDrawable middle = (BitmapDrawable) getResources().getDrawable(R.drawable.text_select_handle_middle_material);
    BitmapDrawable right = (BitmapDrawable) getResources().getDrawable(R.drawable.text_select_handle_right_material);
    // NinePatchDrawable cursor = (NinePatchDrawable) getResources().getDrawable(R.drawable.text_cursor_material);
    left.setColorFilter(cf);
    right.setColorFilter(cf);
    middle.setColorFilter(cf);
    // cursor.setColorFilter(cf); this does not work: cursor still white!
}

但是,虽然这适用于leftrightmiddle,但9补丁cursor仍有问题,因为我无法做到得到它。