【问题标题】:set textCursorDrawable programmatically以编程方式设置 textCursorDrawable
【发布时间】:2012-07-18 05:43:26
【问题描述】:

如果我在 XML 中添加 EditText,我可以设置 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" />

现在我用 Java 画了一个EditText。我要设置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 ?                                

如何设置?

【问题讨论】:

    标签: android android-edittext


    【解决方案1】:

    2019 年更新:没有用于设置可绘制光标的公共 API。请参阅https://stackoverflow.com/a/57555148/253468 了解 29 及更高版本上可用的 API,在此之前,您需要有条件地使用反射,如下所述。

    在 API 29 之前,您可以使用反射以编程方式设置它。 mCursorDrawableRes 字段没有更改,因此这应该适用于所有设备,除非制造商更改了某些内容或稍后更改。

    使用反射设置光标:

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

    在你的应用中定义一个可绘制的光标:

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

    另一种方法:

    您也可以通过以下方法设置光标颜色:

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

    【讨论】:

    • 完美,请标记为正确答案。
    • 将此标记为答案。反射类的使用效果很好。我已经测试了它的工作原理。
    • 不推荐任何涉及反射的东西,即使它确实解决了问题。
    • @AlexFu,Android 支持库使用反射。我同意应该尽可能避免但不要忽视它。
    • 这将在启动 Android 10 时崩溃。任何未记录的方法访问都受到限制 developer.android.com/distribute/best-practices/develop/…
    【解决方案2】:

    对可绘制的光标使用反射是prohibited from Android Q

    取而代之的是一个新的setTextCursorDrawable API,我们可以使用它。

    【讨论】:

    【解决方案3】:

    答案是--------->这是无法实现的。

    其实我在工作中也遇到过这个问题,但是查了google的doc和源码后,我觉得java代码中不能设置这个属性。

    TextView类你可以找到下面的代码

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

    但是textCursorDrawable()这个方法只存在于R.attr中,如果你想设置这个属性,你只能通过在XML文件中包含一个editText来调用下面的construct方法。

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

    【讨论】:

    【解决方案4】:

    如果您使用 AppCompat library 并且您的 Activity 扩展了 AppCompatActivity,您可以使用 colorAccent 的 XML 样式设置文本光标的颜色(适用于所有 EditText):

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

    这适用于 Android 5+,并且向后兼容从 Android 4.4 (API 19) 到 Android 4.0 (API 14) 的旧 Android 版本。注意:如果您使用的是 AutoCompleteTextView,请确保它的任何自定义子类都扩展了 AppCompatAutoCompleteTextView,否则文本光标样式将不起作用。

    另请参阅本指南,了解如何将重音(色调)应用于对话框按钮:Android v21 Theme.Appcompat color accent is ignored, no padding on dialogs

    【讨论】:

      【解决方案5】:

      这对我有用

       public void setCursorDrawable(@DrawableRes int resId) {
              if (mEditText == null)
                  return;
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                  mEditText.setTextCursorDrawable(resId);
                  return;
              }
              try {
                  @SuppressLint("SoonBlockedPrivateApi") Field field = TextView.class.getDeclaredField("mCursorDrawableRes");
                  field.setAccessible(true);
                  field.set(mEditText, resId);
              } catch (Throwable throwable) {
                  Logger.e(TAG, throwable);
              }
          }
      }
      

      【讨论】:

        【解决方案6】:

        你应该使用 TextInputLayout 你在 2020 年?,它适用于所有设备

        <com.google.android.material.textfield.TextInputLayout
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="30dp"
                android:layout_marginTop="26dp"
                android:layout_marginEnd="30dp"
                android:theme="@style/TextInputLayoutAppearance"
                app:endIconMode="clear_text"
                app:hintEnabled="false">
        
                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/gallery_search"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:fontFamily="@font/inter_medium"
                    android:hint="Hint here"
                    android:inputType="text"
                    android:cursorVisible="true"
                    android:focusable="true"
                    />
        
            </com.google.android.material.textfield.TextInputLayout>
        

        这是主要的不要忘记添加这个,你可以从这里改变光标的颜色

        <style name="TextInputLayoutAppearance" parent="Widget.Design.TextInputLayout">
                <item name="colorControlNormal">@color/black</item>
                <item name="colorControlActivated">@color/black</item>
                <item name="colorControlHighlight">@color/blue</item>
            </style>
        

        有关 TextInputLayout 的更多信息,请访问:- https://material.io/develop/android/components/text-fields

        【讨论】:

        • 问题是关于如何以编程方式进行...您的答案仅在 XML 中描述。
        猜你喜欢
        • 1970-01-01
        • 2021-11-21
        • 2018-11-26
        • 2011-04-18
        • 2016-02-15
        • 2014-07-26
        • 1970-01-01
        • 2011-06-06
        • 2012-02-12
        相关资源
        最近更新 更多