set textCursorDrawable programmatically

倖福魔咒の 提交于 2019-12-17 07:16:13

问题


If I add an EditText in XML I can set textCursorDrawable="@null":

<EditText
    android:id="@+id/txtE3Casecode4"
    android:layout_width="30dp"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:background="#C7C7C5"
    android:textCursorDrawable="@null"
    android:ems="10"
    android:inputType="number"
    android:maxLength="2"
    android:text="01"
    android:textColor="#000000" />

Now I draw an EditText in Java. I want set android:textCursorDrawable="@null".

LinearLayout.LayoutParams paramtext = new LinearLayout.LayoutParams(
    LinearLayout.LayoutParams.FILL_PARENT,
    LinearLayout.LayoutParams.WRAP_CONTENT);
EditText txtOther = new EditText(this);
txtOther.setLayoutParams(paramtext);
txtOther.setBackgroundColor(Color.WHITE);
txtOther.setTextColor(Color.BLACK);
txtOther.setId(99999);
// txtOther.setCursorDrawable ?                                

How do set it?


回答1:


There is no public API to set the cursor drawable. You can set it programmatically by using reflection. The field mCursorDrawableRes hasn't changed so this should work on all devices, unless a manufacturer changed something or it is later changed.

Use reflection to set the cursor:

EditText yourEditText = new EditText(context);

...

try {
    // https://github.com/android/platform_frameworks_base/blob/kitkat-release/core/java/android/widget/TextView.java#L562-564
    Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
    f.setAccessible(true);
    f.set(yourEditText, R.drawable.cursor);
} catch (Exception ignored) {
}

Define a cursor drawable in your app:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="#ff000000" />

    <size android:width="1dp" />

</shape>

Another approach:

You can also set the cursor color with the following method:

public static void setCursorDrawableColor(EditText editText, int color) {
    try { 
        Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
        fCursorDrawableRes.setAccessible(true);
        int mCursorDrawableRes = fCursorDrawableRes.getInt(editText);
        Field fEditor = TextView.class.getDeclaredField("mEditor");
        fEditor.setAccessible(true);
        Object editor = fEditor.get(editText);
        Class<?> clazz = editor.getClass();
        Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
        fCursorDrawable.setAccessible(true);
        Drawable[] drawables = new Drawable[2];
        drawables[0] = editText.getContext().getResources().getDrawable(mCursorDrawableRes);
        drawables[1] = editText.getContext().getResources().getDrawable(mCursorDrawableRes);
        drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN);
        drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN);
        fCursorDrawable.set(editor, drawables);
    } catch (Throwable ignored) {
    } 
} 



回答2:


Using reflection for the cursor drawable is prohibited from Android Q.

Instead, there is a new setTextCursorDrawable API and we can use this.




回答3:


the answer is ---------------------> It's unattainable.

Actually, I also met this problem in my work, but after checking google's doc and source code, I fond that you cannot set this attribute in java code.

In TextView class you can find the code below

case com.android.internal.R.styleable.TextView_textCursorDrawable:
    mCursorDrawableRes = a.getResourceId(attr, 0);
    break;

but the method textCursorDrawable() is only existed in R.attr, if you wanna set this attribute, you can only call the construct method below by including a editText in XML file.

public EditText(Context context, AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.editTextStyle);
}



回答4:


If you use the AppCompat library and your Activity extends AppCompatActivity, you can set the color of the text cursor (for all EditTexts) using an XML style of colorAccent:

<style name="AppTheme" parent="@style/Theme.AppCompat">
    <item name="colorAccent">#FF4081</item>
</style>

This works on Android 5+ and is backwards compatible with older Android versions from Android 4.4 (API 19) to Android 4.0 (API 14). Note: If you're using an AutoCompleteTextView, ensure that any custom subclass of it extends AppCompatAutoCompleteTextView, otherwise the text cursor styling will not work.

See also this guide, for how to apply the color accent (tint) to Dialog buttons: Android v21 Theme.Appcompat color accent is ignored, no padding on dialogs



来源:https://stackoverflow.com/questions/11554078/set-textcursordrawable-programmatically

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