1. 程式人生 > >程式碼中動態和佈局檔案中靜態改變Edittext游標樣式方法

程式碼中動態和佈局檔案中靜態改變Edittext游標樣式方法

這兩種修改游標樣式的方法各有優缺點,我會在後面說明。建議使用第一種
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)