2016-11-30 88 views
13

我有EditView,想要更改顏色PROGRAMATICALLY代碼如何在EditView(PROGRAMATICALLY)上更改氣泡顏色(在光標下)?

要更改光標的顏色,我使用this code

但如何更改EditView上的圓圈顏色通過編程可以編程? enter image description here

+0

的可能的複製[如何改變在機器人的EditText氣泡顏色(下光標)?](http://stackoverflow.com/questions/35337909/how-to-change-edittext-bubble-color-under -cursor-in-android) –

+0

@Jack您是否看過問題?改變顏色編程的代碼! – NickUnuchek

+0

您可以創建一個新的主題,將所需的顏色設置爲colorAccent並以編程方式設置主題。 –

回答

10

您將需要使用反射來爲選擇手柄(氣泡)着色。

用法示例:

try { 
    EditTextTint.applyColor(editText, Color.CYAN); 
} catch (EditTextTint.EditTextTintError e) { 
    e.printStackTrace(); 
} 

EditTextTint.java:今天早上我寫了下面的類

import android.content.res.Resources; 
import android.graphics.PorterDuff; 
import android.graphics.drawable.Drawable; 
import android.support.annotation.ColorInt; 
import android.support.annotation.NonNull; 
import android.widget.EditText; 
import android.widget.TextView; 
import java.lang.reflect.Field; 

/** 
* Tint the cursor and select handles of an {@link EditText} programmatically. 
*/ 
public class EditTextTint { 

    /** 
    * Set the cursor and handle colors for an {@link EditText} programmatically. 
    * 
    * @param editText 
    *  The {@link EditText} to tint 
    * @param color 
    *  The color to apply for the cursor and select handles 
    * @throws EditTextTintError 
    *  If an error occured while attempting to tint the view. 
    */ 
    public static void applyColor(@NonNull EditText editText, @ColorInt int color) throws EditTextTintError { 
    EditTextTint editTextTint = new Builder(editText) 
     .setCursorColor(color) 
     .setSelectHandleLeftColor(color) 
     .setSelectHandleRightColor(color) 
     .setSelectHandleMiddleColor(color) 
     .build(); 
    editTextTint.apply(); 
    } 

    private final EditText editText; 
    private final Integer cursorColor; 
    private final Integer selectHandleLeftColor; 
    private final Integer selectHandleRightColor; 
    private final Integer selectHandleMiddleColor; 

    private EditTextTint(Builder builder) { 
    editText = builder.editText; 
    cursorColor = builder.cursorColor; 
    selectHandleLeftColor = builder.selectHandleLeftColor; 
    selectHandleRightColor = builder.selectHandleRightColor; 
    selectHandleMiddleColor = builder.selectHandleMiddleColor; 
    } 

    /** 
    * Sets the color for the cursor and handles on the {@link EditText editText}. 
    * 
    * @throws EditTextTintError 
    *  if an error occurs while tinting the view. 
    */ 
    public void apply() throws EditTextTintError { 
    try { 
     Resources res = editText.getContext().getResources(); 

     // Get the editor 
     Field field = TextView.class.getDeclaredField("mEditor"); 
     field.setAccessible(true); 
     Object editor = field.get(editText); 

     if (cursorColor != null) { 
     // Get the cursor drawable, tint it, and set it on the TextView Editor 
     field = TextView.class.getDeclaredField("mCursorDrawableRes"); 
     field.setAccessible(true); 
     int cursorDrawableRes = field.getInt(editText); 
     Drawable cursorDrawable = res.getDrawable(cursorDrawableRes).mutate(); 
     cursorDrawable.setColorFilter(cursorColor, PorterDuff.Mode.SRC_IN); 
     Drawable[] drawables = {cursorDrawable, cursorDrawable}; 
     field = editor.getClass().getDeclaredField("mCursorDrawable"); 
     field.setAccessible(true); 
     field.set(editor, drawables); 
     } 

     String[] resFieldNames = {"mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes"}; 
     String[] drawableFieldNames = {"mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter"}; 
     Integer[] colors = {selectHandleLeftColor, selectHandleRightColor, selectHandleMiddleColor}; 

     for (int i = 0; i < resFieldNames.length; i++) { 
     Integer color = colors[i]; 
     if (color == null) { 
      continue; 
     } 

     String resFieldName = resFieldNames[i]; 
     String drawableFieldName = drawableFieldNames[i]; 

     field = TextView.class.getDeclaredField(resFieldName); 
     field.setAccessible(true); 
     int selectHandleRes = field.getInt(editText); 

     Drawable selectHandleDrawable = res.getDrawable(selectHandleRes).mutate(); 
     selectHandleDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); 

     field = editor.getClass().getDeclaredField(drawableFieldName); 
     field.setAccessible(true); 
     field.set(editor, selectHandleDrawable); 
     } 
    } catch (Exception e) { 
     throw new EditTextTintError("Error applying tint to " + editText, e); 
    } 
    } 

    public static class Builder { 

    final EditText editText; 
    Integer cursorColor; 
    Integer selectHandleLeftColor; 
    Integer selectHandleRightColor; 
    Integer selectHandleMiddleColor; 

    public Builder(@NonNull EditText editText) { 
     this.editText = editText; 
    } 

    public Builder setCursorColor(@ColorInt int cursorColor) { 
     this.cursorColor = cursorColor; 
     return this; 
    } 

    public Builder setSelectHandleLeftColor(@ColorInt int selectHandleLeftColor) { 
     this.selectHandleLeftColor = selectHandleLeftColor; 
     return this; 
    } 

    public Builder setSelectHandleRightColor(@ColorInt int selectHandleRightColor) { 
     this.selectHandleRightColor = selectHandleRightColor; 
     return this; 
    } 

    public Builder setSelectHandleMiddleColor(@ColorInt int selectHandleMiddleColor) { 
     this.selectHandleMiddleColor = selectHandleMiddleColor; 
     return this; 
    } 

    public EditTextTint build() { 
     return new EditTextTint(this); 
    } 

    } 

    public static class EditTextTintError extends Exception { 

    public EditTextTintError(String message, Throwable cause) { 
     super(message, cause); 
    } 
    } 

} 

注:這應該從果凍豆工作,牛軋糖。但是,由於它使用反射來獲取和設置專用字段,因此這可能會在未來的Android版本或製造商對EditText進行更改時破壞。

+0

你是我的英雄。 –

-1

試試這個:

<color name="colorAccent">#263238</color> 

改變這種顏色代碼#263238改變值值/ colors.xml文件到您自己的顏色代碼,所以這將是適用於所有的項目。 希望這會幫助你。

+0

我知道風格和主題,你讀過的問題?我想在代碼上改變它編程! – NickUnuchek

+0

雅你最近編輯了你的帖子,我以爲你不需要改變整個項目的光標顏色,所以我建議這個帖子, –

2

以下方法適用於所有遊標氣泡,例如左,右和中心。我的意思是,除了你的要求,它適用於左側和右側。

例如; Beside your request, It works for both left and right ones

您可以通過刪除兩個數組中的左側和右側字段名稱來更改該方法以僅對中心句柄着色。

public static void colorHandles(TextView view, int color) { 
    try { 
    Field editorField = TextView.class.getDeclaredField("mEditor"); 
    if (!editorField.isAccessible()) { 
     editorField.setAccessible(true); 
    } 

    Object editor = editorField.get(view); 
    Class<?> editorClass = editor.getClass(); 

    String[] handleNames = {"mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter"}; 
    String[] resNames = {"mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes"}; 

    for (int i = 0; i < handleNames.length; i++) { 
     Field handleField = editorClass.getDeclaredField(handleNames[i]); 
     if (!handleField.isAccessible()) { 
     handleField.setAccessible(true); 
     } 

     Drawable handleDrawable = (Drawable) handleField.get(editor); 

     if (handleDrawable == null) { 
     Field resField = TextView.class.getDeclaredField(resNames[i]); 
     if (!resField.isAccessible()) { 
      resField.setAccessible(true); 
     } 
     int resId = resField.getInt(view); 
     handleDrawable = view.getResources().getDrawable(resId); 
     } 

     if (handleDrawable != null) { 
     Drawable drawable = handleDrawable.mutate(); 
     drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); 
     handleField.set(editor, drawable); 
     } 
    } 
    } catch (Exception e) { 
    e.printStackTrace(); 
    } 
} 
相關問題