到目前为止,我一直在使用反射,因此请更新editTexts的选择句柄。在我更新为目标API 29(Q)之前,它一直工作良好。
似乎Google进行了一些更新(或完全不确定Java),但是我现在收到类似以下消息:
访问隐藏字段Landroid / widget / Editor;-> mDrawableForCursor:Landroid / graphics / drawable / Drawable; (暗灰色列表,反射)
从好的方面来说,API 29(经过很多年)具有通过编程方式设置手柄颜色的稳定方法。不幸的是,它不能像我所发现的那样向后兼容,并且它也破坏了api 28的功能。api 28之下的所有内容都可以在反射下正常工作。在我的代码下方,该代码现在可用于除API 28以外的任何功能
/**
* Sets the color for the cursor and handles on the {@link EditText editText}.
*
* @throws EditTextTintError if an error occurs while tinting the view.
*/
public void apply() throws EditTextTintError {
try {
// Get the editor
Field field = TextView.class.getDeclaredField("mEditor");
field.setAccessible(true);
Object editor = field.get(editText);
if (cursorColor != null) {
editText.setHighlightColor(ColorUtils.setAlphaComponent(cursorColor, 40));
// Get the cursor drawable, tint it, and set it on the TextView Editor
// Get the cursor resource id
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ColorFilter colorFilter = new BlendModeColorFilter(cursorColor, BlendMode.SRC_ATOP);
editText.getTextCursorDrawable().mutate().setColorFilter(colorFilter);
editText.getTextSelectHandle().mutate().setColorFilter(colorFilter);
editText.getTextSelectHandleLeft().mutate().setColorFilter(colorFilter);
editText.getTextSelectHandleRight().mutate().setColorFilter(colorFilter);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
try {
Field fieldP = TextView.class.getDeclaredField("mCursorDrawableRes");
fieldP.setAccessible(true);
int drawableResId = fieldP.getInt(editText);
// Get the editor
fieldP = TextView.class.getDeclaredField("mEditor");
fieldP.setAccessible(true);
Object editorP = fieldP.get(editText);
// Get the drawable and set a color filter
Drawable drawable = ContextCompat.getDrawable(editText.getContext(), drawableResId);
drawable.setColorFilter(cursorColor, PorterDuff.Mode.SRC_ATOP);
// Set the drawables
fieldP = editorP.getClass().getDeclaredField("mDrawableForCursor");
fieldP.setAccessible(true);
fieldP.set(editorP, drawable);
} catch (final Exception ignored) {
ignored.printStackTrace();
}
} else {
String[] resFieldNames = {"mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes"};
String[] drawableFieldNames = {"mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter"};
Integer[] colors = {selectHandleLeftColor, selectHandleRightColor, selectHandleMiddleColor};
for (int i = 0; i < resFieldNames.length; i++) {
Integer color = colors[i];
if (color == null) {
continue;
}
String resFieldName = resFieldNames[i];
String drawableFieldName = drawableFieldNames[i];
field = TextView.class.getDeclaredField(resFieldName);
field.setAccessible(true);
int selectHandleRes = field.getInt(editText);
Drawable selectHandleDrawable = ContextCompat.getDrawable(editText.getContext(), selectHandleRes).mutate();
selectHandleDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
field = editor.getClass().getDeclaredField(drawableFieldName);
field.setAccessible(true);
field.set(editor, selectHandleDrawable);
}
}
}
} catch (Exception e) {
throw new EditTextTintError("Error applying tint to " + editText, e);
}
}
基本上,Android P的情况已被Google的最新更新所破坏:(
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// insert working code here :D
}
我的问题,是否有人能够使用目标api 29以编程方式设置在api 28上运行的设备的手柄颜色?
答案 0 :(得分:0)
您不能用textField.setTextSelectHandle(drawable)
这样做吗?