set textCursorDrawable programmatically
Update 2019: There is no public API to set the cursor drawable. See https://stackoverflow.com/a/57555148/253468 for API available on 29 and above, before that conditionally you'll need to use reflection as described below.
Before API 29 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) {
}
}
How to Change programmatically Edittext Cursor Color in android?
Using some reflection did the trick for me
Java:
// 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);
XML:
<?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>
Here is a method that you can use that doesn't need an XML:
public static void setCursorColor(EditText view, @ColorInt int color) {
try {
// Get the cursor resource id
Field field = TextView.class.getDeclaredField("mCursorDrawableRes");
field.setAccessible(true);
int drawableResId = field.getInt(view);
// Get the editor
field = TextView.class.getDeclaredField("mEditor");
field.setAccessible(true);
Object editor = field.get(view);
// Get the drawable and set a color filter
Drawable drawable = ContextCompat.getDrawable(view.getContext(), drawableResId);
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
Drawable[] drawables = {drawable, drawable};
// Set the drawables
field = editor.getClass().getDeclaredField("mCursorDrawable");
field.setAccessible(true);
field.set(editor, drawables);
} catch (Exception ignored) {
}
}
Set EditText cursor color
Setting the android:textCursorDrawable
attribute to @null
should result in the use of android:textColor
as the cursor color.
Attribute "textCursorDrawable" is available in API level 12 and higher
change edittext cursor color
In your EditText properties, there is an attribute android:textCursorDrawable
Now set it to @null like,
android:textCursorDrawable="@null"
So now your EditText Cursor is same as your EditText TextColor.
Reference From Set EditText cursor color
Setting EditText Cursor Color With Reflection Method
OK, after digging into the Android Pie Source Code, I found out that Google has changed mCursorDrawable
to mDrawableForCursor
, and also changed its type from a two element Drawable
array to simply Drawable
, so I made some changes based on the original reflection method, and now it works for Android P:
public static void setEditTextCursorColor(EditText editText, int color) {
try {
// Get the cursor resource id
Field field = TextView.class.getDeclaredField("mCursorDrawableRes");
field.setAccessible(true);
int drawableResId = field.getInt(editText);
// Get the editor
field = TextView.class.getDeclaredField("mEditor");
field.setAccessible(true);
Object editor = field.get(editText);
// Get the drawable and set a color filter
Drawable drawable = ContextCompat.getDrawable(editText.getContext(), drawableResId);
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
// Set the drawables
if(Build.VERSION.SDK_INT >= 28){//set differently in Android P (API 28)
field = editor.getClass().getDeclaredField("mDrawableForCursor");
field.setAccessible(true);
field.set(editor, drawable);
}else {
Drawable[] drawables = {drawable, drawable};
field = editor.getClass().getDeclaredField("mCursorDrawable");
field.setAccessible(true);
field.set(editor, drawables);
}
//optionally set the "selection handle" color too
setEditTextHandleColor(editText, color);
} catch (Exception ignored) {}
}
Side note, I really wish Google could just add a public method like setCursorDrawable() or something like that, that would've been much easier.
How to get height of default cursor drawable?
Using reflection i could find the height of Cursor. It has worked for Samsung edge s7. It will probably work for all devices, if the manufacturer did not make any changes to mCursorDrawableRes.
public int getHeightofCursor(Context context, EditText editText) throws Exception {
Field cursor = TextView.class.getDeclaredField("mCursorDrawableRes");
cursor.setAccessible(true);
int resid = cursor.getInt(editText);
Drawable cursorDrawable = context.getResources().getDrawable(resid);
return cursorDrawable.getIntrinsicHeight();
}
Set Entry Cursor visibility // color
You can use a custom Entry:
CustomEntry
internal class CustomEntry : EntryHandler
{
public CustomEntry()
{
}
protected override void ConnectHandler(AppCompatEditText platformView)
{
base.ConnectHandler(platformView);
platformView.ShowSoftInputOnFocus = false;
//platformView.SetCursorVisible(false); //not sure why it is not working
//replaced by this approah:
#if ANDROID29_0_OR_GREATER
platformView.SetTextCursorDrawable(Resource.Drawable.invisible_cursor);
#else
//code to handle it for API< 29, check link in edit section of my answer
#endif
}
}
MauiProgram.cs
#if ANDROID
builder.ConfigureMauiHandlers((handlers) =>
{
handlers.AddHandler(typeof(Entry), typeof(CustomEntry));
}
#endif
invisible_cursor.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent"></solid>
</shape>
EDIT
SetTextCursorDrawable()
was introduced in API29+, to support earlier Android version I invite you to take a look at set textCursorDrawable programmatically, you can handdle that case in the #else
of #if ANDROID29_0_OR_GREATER
(code above edited).
Related Topics
Uninstall App Silently with System Privileges
Remove Android Default Action Bar
Android: Refreshing The Gallery After Saving New Images
How to Prevent Nfc Tag Cloning
How to Save Data from Camera to Disk Using Mediastore on Android
How to Make a Linearlayout Scrollable
How to Set Margins for Textview Programmatically
How to Get Current Process Name in Android
How to Use The Limit Argument in an Sqlite Query with Android
How to Open The Avd Manager on Ubuntu Linux from The Command Line
Android: Why Does Long Click Also Trigger a Normal Click
Android Device Phone Call Ability
Generating iOS and Android Icons in Cordova/Phonegap
Android Studio Keyboard Shortcut Control
Warning: Quick Boot/Snapshots Not Supported on This Machine
Get Context of Test Project in Android Junit Test Case
Confused About Testcompile and Androidtestcompile in Android Gradle