程式碼中動態和佈局檔案中靜態改變Edittext游標樣式方法
阿新 • • 發佈:2019-01-27
這兩種修改游標樣式的方法各有優缺點,我會在後面說明。建議使用第一種
1、佈局檔案中修改Edittext游標樣式(常用)
drawable下,建立游標樣式檔案:edittext_cursor_style
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:width="1dp" />
<solid android:color="#f5c2c5" />
</shape>
在Edittext中引用即可
<EditText
android:id="@+id/edittext"
android:layout_width="200dp"
android:layout_height="40dp"
android:layout_marginLeft="30dp"
android:layout_marginTop="50dp"
android:background="#dedede"
android:paddingLeft ="3dp"
android:singleLine="true"
android:textCursorDrawable="@drawable/edittext_cursor_style"
/>
2、在程式碼中動態修改游標樣式:如,一開始游標是A顏色,在點選Edittext的時候,游標顏色就要變化
效果圖
選中前:
選中後:
程式碼:使用反射原理(最後有注意事項,需要留意)
佈局檔案:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#EEEED1"
android:orientation="vertical"
>
<EditText
android:id="@+id/edittext"
android:layout_width="200dp"
android:layout_height="40dp"
android:layout_marginLeft="30dp"
android:layout_marginTop="50dp"
android:background="#dedede"
android:paddingLeft="3dp"
android:singleLine="true"
android:textCursorDrawable="@drawable/edittext_cursor_style"
/>
</LinearLayout>
Activity:
package com.chen.customviewdemo;
import android.app.Activity;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.lang.reflect.Field;
/**
* 動態變換Edittext的游標顏色
*/
public class MainActivity_11 extends Activity {
private EditText et;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_11);
et = (EditText) findViewById(R.id.edittext);
//預設開啟數字鍵盤(InputType的型別還有很多,不一一展示了)
//et.setInputType(InputType.TYPE_CLASS_NUMBER);
et.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
fCursorDrawableRes.setAccessible(true);
int mCursorDrawableRes = fCursorDrawableRes.getInt(et);
Field fEditor = TextView.class.getDeclaredField("mEditor");
fEditor.setAccessible(true);
Object editor = fEditor.get(et);
Class<?> clazz = editor.getClass();
Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
fCursorDrawable.setAccessible(true);
Drawable[] drawables = new Drawable[1];
drawables[0] = et.getContext().getResources().getDrawable(mCursorDrawableRes);
drawables[0].setColorFilter(0xff00ff00, PorterDuff.Mode.SRC_IN);
fCursorDrawable.set(editor, drawables);
} catch (Exception ignored) {
Toast.makeText(MainActivity_11.this, "出異常了", Toast.LENGTH_SHORT).show();
}
}
});
}
}
注:
1、使用第一種方法(佈局中修改),可以自由改變游標的寬度,但是帶程式碼中改變,很遺憾,我沒有找到方法。
2、在使用反射方法時,會在控制檯上看到警告日誌:
提示:
drawables[0] = et.getContext().getResources().getDrawable(mCursorDrawableRes);
這句話有java.lang.RuntimeException
,但是不影響使用
詳細日誌:
08-19 11:45:43.513 693-693/com.chen.customviewdemo W/Resources: Drawable android:drawable/text_cursor_material has unresolved theme attributes! Consider using Resources.getDrawable(int, Theme) or Context.getDrawable(int).
java.lang.RuntimeException
at android.content.res.Resources.getDrawable(Resources.java:786)
at android.widget.Editor$InsertionHandleView.getHotspotX(Editor.java:3921)
at android.widget.Editor$HandleView.updateDrawable(Editor.java:3535)
at android.widget.Editor$HandleView.<init>(Editor.java:3526)
at android.widget.Editor$InsertionHandleView.<init>(Editor.java:3877)
at android.widget.Editor$InsertionPointCursorController.getHandle(Editor.java:4185)
at android.widget.Editor$InsertionPointCursorController.access$300(Editor.java:4149)
at android.widget.Editor.onTouchUpEvent(Editor.java:1814)
at android.widget.TextView.onTouchEvent(TextView.java:8373)
at android.view.View.dispatchTouchEvent(View.java:9306)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2403)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1737)
at android.app.Activity.dispatchTouchEvent(Activity.java:2820)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2364)
at android.view.View.dispatchPointerEvent(View.java:9526)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4255)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4121)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3662)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3715)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3681)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3807)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3689)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3864)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3662)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3715)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3681)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3689)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3662)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5947)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5921)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5882)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6050)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:323)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5432)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:735)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
08-19 11:45:43.516 693-693/com.chen.customviewdemo W/Resources: Drawable android:drawable/text_cursor_material has unresolved theme attributes! Consider using Resources.getDrawable(int, Theme) or Context.getDrawable(int).
java.lang.RuntimeException
at android.content.res.Resources.getDrawable(Resources.java:786)
at com.chen.customviewdemo.MainActivity_11$1.onClick(MainActivity_11.java:46)
at android.view.View.performClick(View.java:5207)
at android.view.View$PerformClick.run(View.java:21177)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5432)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:735)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)