2016-11-30 25 views
13

Mam EditView i chcę zmienić kolor PROGRAMATYCZNIE na kod.Jak zmienić kolor bańki (pod kursorem) na EditView (PROGRAMATYCZNIE)?

Aby zmienić kolor kursora, używam this code.

Ale jak zmienić kolor koła na EditView PROGRAMATYCZNIE na kodzie? enter image description here

+0

Możliwy duplikat [Jak zmienić kolor EditText bubble (pod kursorem) w Android?] (Http://stackoverflow.com/questions/35337909/how-to-change-edittext-bubble-color-under -cursor-in-android) –

+0

@Jack Czy przeczytałeś pytanie? zmień kolor programowy na kod !!! – NickUnuchek

+0

Możesz utworzyć nową kompozycję z wymaganym zestawem kolorów do colorAccent i ustawić program tematycznie. –

Odpowiedz

10

Będziesz musiał użyć odbicia, aby zabarwić wybrane uchwyty (bąbelki). Pisałem następujące klasy rano:

Przykład użycia:

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

} 

Uwaga: To powinno działać z Jelly Bean na Nugat. Jednak, ponieważ używa refleksji, aby uzyskać i ustawić prywatne pola, może to przerwać w przyszłych wydaniach Androida lub jeśli producent wprowadził zmiany w EditText.

+0

Jesteś moim bohaterem. –

-1

spróbuj to: zmiana wartości w pliku wartości/colors.xml

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

zmienić ten kod koloru # 263238 do własnego kodu kolorów, tak, że będzie mieć zastosowanie do wszystkich projektów. Mam nadzieję, że to ci pomoże.

+0

Wiem o stylach i tematach, czy przeczytałeś pytanie? Chcę zmienić programowo na kod !!! – NickUnuchek

+0

Ostatnio edytowałeś swój post, myślałem, że nie potrzebujesz zmieniać koloru kursora w całym projekcie, więc zasugerowałem, że post, –

2

Poniższa metoda działa dla wszystkich bąbelków kursorów, takich jak lewy, prawy i środkowy. Mam na myśli, oprócz twojej prośby, działa zarówno dla lewej, jak i prawej.

Na przykład; Beside your request, It works for both left and right ones

Możesz zmienić tę metodę, aby tylko pokolorować środkowy uchwyt, usuwając lewą i prawą nazwę pola w dwóch tablicach.

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(); 
    } 
}