无法将 colorFilter 应用于文本选择句柄
Can't apply a colorFilter to text selection handles
我正在尝试为我的应用程序添加 material 文本选择句柄。我从 SDK 获得了 middle/right/left 句柄(位图)和文本光标(9 补丁)的可绘制对象,并设置:
<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 中,这些可绘制对象使用 android:tint
属性在 XML 中使用特定颜色着色,我无法在 API<21 上使用该属性。所以我试图在运行时设置一个颜色过滤器。
文本光标没有着色。我认为这可能是因为它是 9 补丁。如何在运行时过滤 9 块可绘制对象?我可能尝试了所有 PorterDuff.Mode
s.
Right/left手柄为黑色,中间手柄为白色。
也就是说,没有一个像我想要的那样是绿色的。为什么?
正如您在上面看到的,我在我的编辑文本下方设置了四个 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 上过滤器也会失败 - 以及与文本选择管理器考虑应用过滤器的 none 个事实相关的问题.
相关源代码来自 TextView
class and from this Editor
hidden helper class 我不知何故找到的。花了一些时间,但仍然不知道为什么我的过滤器被忽略了。
致@pskink:让 cursor
成为过滤后的可绘制对象,我可以:
<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>
这会影响编辑选择(因为我覆盖了默认光标)但它又没有着色。
这只是部分答案,我们也可以认为它很糟糕,因为它是一种解决方法。通过指向 XML 文件而不是原始 png 文件,我能够仅加载编辑文本(或任何其他选择内容)内的句柄(即 BitmapDrawables)。 IE。我设置:
<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 可绘制对象,例如:
<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" />
如果我过滤这些可绘制对象,我发现它们在视图 和选择中 both 着色。所以我改变了我的方法:
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!
}
然而,虽然这适用于 left
、right
和 middle
,但 9 补丁 cursor
仍然存在问题,因为我不能染上颜色。
您需要覆盖 Activity:
使用的默认资源
// your activity source file
Resources res;
@Override
public Resources getResources() {
if (res == null) {
res = new TintResources(super.getResources());
}
return res;
}
自定义资源 class 将覆盖 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 没有 getter 访问这些 Drawables 的方法
我正在尝试为我的应用程序添加 material 文本选择句柄。我从 SDK 获得了 middle/right/left 句柄(位图)和文本光标(9 补丁)的可绘制对象,并设置:
<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 中,这些可绘制对象使用 android:tint
属性在 XML 中使用特定颜色着色,我无法在 API<21 上使用该属性。所以我试图在运行时设置一个颜色过滤器。
文本光标没有着色。我认为这可能是因为它是 9 补丁。如何在运行时过滤 9 块可绘制对象?我可能尝试了所有
PorterDuff.Mode
s.Right/left手柄为黑色,中间手柄为白色。
也就是说,没有一个像我想要的那样是绿色的。为什么?
正如您在上面看到的,我在我的编辑文本下方设置了四个 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 上过滤器也会失败 - 以及与文本选择管理器考虑应用过滤器的 none 个事实相关的问题.
相关源代码来自 TextView
class and from this Editor
hidden helper class 我不知何故找到的。花了一些时间,但仍然不知道为什么我的过滤器被忽略了。
致@pskink:让 cursor
成为过滤后的可绘制对象,我可以:
<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>
这会影响编辑选择(因为我覆盖了默认光标)但它又没有着色。
这只是部分答案,我们也可以认为它很糟糕,因为它是一种解决方法。通过指向 XML 文件而不是原始 png 文件,我能够仅加载编辑文本(或任何其他选择内容)内的句柄(即 BitmapDrawables)。 IE。我设置:
<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 可绘制对象,例如:
<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" />
如果我过滤这些可绘制对象,我发现它们在视图 和选择中 both 着色。所以我改变了我的方法:
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!
}
然而,虽然这适用于 left
、right
和 middle
,但 9 补丁 cursor
仍然存在问题,因为我不能染上颜色。
您需要覆盖 Activity:
使用的默认资源// your activity source file
Resources res;
@Override
public Resources getResources() {
if (res == null) {
res = new TintResources(super.getResources());
}
return res;
}
自定义资源 class 将覆盖 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 没有 getter 访问这些 Drawables 的方法