Can't apply a colorFilter to text selection handles

守給你的承諾、 提交于 2019-12-10 11:08:42

问题


I'm trying to bring material text selection handles to my app. I got drawables from the SDK for middle/right/left handle (bitmaps) and text cursor (9-patch), and set:

<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>

It works as expected. However, in Lollipop these drawables are tinted with a particular color in XML using the android:tint attribute, which I can't use on API<21. So I'm trying to set a color filter at runtime.

  • Text cursor does not get tinted. I think this might be due to it being a 9 patch. How can a 9-patch drawable be filtered at runtime? I tried probably all of PorterDuff.Modes.

  • Right/left handles are black, while middle handle is white.

I.e., non of them is green as I would like. Why?

As you can see above, I set up four ImageView below my edit text, and they instead get tinted.

   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);
   }

Looks like here we have both a 9-patch tinting issue - since filter fails even on test ImageViews - and an issue related to the fact that none of the applied filters get considered by the text selection manager.

Relevant source code about that is from the TextView class and from this Editor hidden helper class which I found somehow. Spent some time on it but still can't tell why my filters are ignored.


To @pskink: let cursor be the filtered drawable, I can have:

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

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

The first won't be tinted, but if I call imageView2.setBackground(cursor), then it's tinted. Also if I have

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

this affects the edit selection (because I override the default cursor) but it's not tinted, again.


回答1:


you need to override the default Resources used by your Activity:

// your activity source file
Resources res;

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

the custom Resources class will override getDrawable() method so you can intercept creating your Drawables and set up the color filter, for example:

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;
    }
}

the same way you can setup other Drawables (@drawable/text_select_handle_*_material), note you need that not direct way since EditText doesn't have getter methods for accessing those Drawables




回答2:


This is just a partial answer, and we can also consider it quite bad, since it's a workaround. I was able to load just the handles (i.e., the BitmapDrawables) inside the edittext (or any other selection stuff) by pointing at XML files rather than at raw png files. I.e. I set:

<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>

where these are xml drawables like:

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

or

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

If I filter these drawables, I found them tinted both in views and in selections. So I altered my method like such:

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!
}

However, while this works for left, right, and middle, something is still wrong with the 9-patch cursor, because I can't get it tinted.



来源:https://stackoverflow.com/questions/28263596/cant-apply-a-colorfilter-to-text-selection-handles

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!