2013-03-21 20 views
93

sto cercando di creare un ColorStateList programatically utilizzando questo:Come si crea ColorStateList in modo programmatico?

ColorStateList stateList = new ColorStateList(states, colors); 

ma non sono sicuro di quello che sono i due parametri.

Come per la documentazione:

public ColorStateList (int[][] states, int[] colors) 

Aggiunto a livello di API 1

Crea un ColorStateList che restituisce la mappatura specificata dagli stati ai colori.

Qualcuno può spiegarmi come si crea questo?

Qual è il significato dell'array bidimensionale per gli stati?

risposta

216

Vedere http://developer.android.com/reference/android/R.attr.html#state_above_anchor per un elenco di stati disponibili.

Se si desidera impostare i colori per disabili, sfocate, gli stati non controllate ecc solo nega gli stati:

int[][] states = new int[][] { 
    new int[] { android.R.attr.state_enabled}, // enabled 
    new int[] {-android.R.attr.state_enabled}, // disabled 
    new int[] {-android.R.attr.state_checked}, // unchecked 
    new int[] { android.R.attr.state_pressed} // pressed 
}; 

int[] colors = new int[] { 
    Color.BLACK, 
    Color.RED, 
    Color.GREEN, 
    Color.BLUE 
}; 

ColorStateList myList = new ColorStateList(states, colors); 
+16

Grazie per le informazioni sugli stati "opposti"! – BVB

+0

Questo può essere usato per cambiare il colore di un fab dalla libreria di progettazione. – Tapirboy

+0

ATTENZIONE: vedere la risposta di Roger Alien (e il suo primo commento) per capire che l'ordine degli stati qui è scadente: poiché "abilitato" è il primo, sovrascriverà altri stati che si verificano in genere mentre un pulsante è abilitato. Meglio mettere l'ultimo "abilitato". (O invece di "abilitato", ultimo elemento vuoto/predefinito.) – ToolmakerSteve

55

La prima dimensione è un array di insiemi di stati, il secondo ist lo stato si imposta. L'array colors elenca i colori per ciascun set di stato corrispondente, pertanto la lunghezza dell'array colors deve corrispondere alla prima dimensione dell'array states (oppure si arresta in modo anomalo quando lo stato viene "utilizzato"). Qui e l'esempio:

ColorStateList myColorStateList = new ColorStateList(
         new int[][]{ 
           new int[]{android.R.attr.state_pressed}, //1 
           new int[]{android.R.attr.state_focused}, //2 
           new int[]{android.R.attr.state_focused, android.R.attr.state_pressed} //3 
         }, 
         new int[] { 
          Color.RED, //1 
          Color.GREEN, //2 
          Color.BLUE //3 
         } 
        ); 

speranza che questo aiuti.

esempio EDIT: un colore lista di stato xml come:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_pressed="true" android:color="@color/white"/> 
    <item android:color="@color/black"/> 
</selector> 

sarebbe simile a questa

ColorStateList myColorStateList = new ColorStateList(
     new int[][]{ 
       new int[]{android.R.attr.state_pressed}, 
       new int[]{} 
     }, 
     new int[] { 
       context.getResources().getColor(R.color.white), 
       context.getResources().getColor(R.color.black) 
     } 
); 
+0

Puoi TE Il modo in cui rappresentare il sotto xml " " utilizzando colorstatelist. – Satish

+0

@SatishKumar controlla la mia modifica, non l'ho ancora testata. –

+1

Vale la pena di dire che per specificare uno stato falso, puoi negarne il valore, quindi se vuoi specificare un colore per quando non è premuto, dovresti usare: new int [] {- ​​android.R.attr.state_pressed} – tinsukE

8

Purtroppo nessuna delle soluzioni funziona per me.

  1. Se non si imposta lo stato premuto inizialmente, non lo rileva.
  2. Se lo si imposta, allora avete bisogno di definire lo stato di vuoto per aggiungere colore predefinito
ColorStateList themeColorStateList = new ColorStateList(
     new int[][]{ 
       new int[]{android.R.attr.state_pressed}, 
       new int[]{android.R.attr.state_enabled}, 
       new int[]{android.R.attr.state_focused, android.R.attr.state_pressed}, 
       new int[]{-android.R.attr.state_enabled}, 
       new int[]{} // this should be empty to make default color as we want 
     }, 
     new int[]{ 
       pressedFontColor, 
       defaultFontColor, 
       pressedFontColor, 
       disabledFontColor, 
       defaultFontColor 
     } 
); 

Questo è il costruttore dal codice sorgente:

/** 
* Creates a ColorStateList that returns the specified mapping from 
* states to colors. 
*/ 
public ColorStateList(int[][] states, int[] colors) { 
    mStateSpecs = states; 
    mColors = colors; 

    if (states.length > 0) { 
     mDefaultColor = colors[0]; 

     for (int i = 0; i < states.length; i++) { 
      if (states[i].length == 0) { 
       mDefaultColor = colors[i]; 
      } 
     } 
    } 
} 
+2

Proprio come un sidenote: devi trattarlo come se fossi un if-elseif. Seleziona il primo stato che è vero. Quindi, se hai lo stato_attivato come primo stato, sarà selezionato prima di state_pressed - a meno che la vista non sia disabilitata. – LeoFarage

+0

FWIW, dato che per ultimo hai un elemento predefinito, non credo che il primo elemento "abilitato" ti faccia del bene. Perché non rimuoverlo completamente? – ToolmakerSteve

1

se si utilizza la risorsa Colori.xml

int[] colors = new int[] { 
       getResources().getColor(R.color.ColorVerificaLunes), 
       getResources().getColor(R.color.ColorVerificaMartes), 
       getResources().getColor(R.color.ColorVerificaMiercoles), 
       getResources().getColor(R.color.ColorVerificaJueves), 
       getResources().getColor(R.color.ColorVerificaViernes) 

     }; 

ColorStateList csl = new ColorStateList(new int[][]{new int[0]}, new int[]{colors[0]}); 

    example.setBackgroundTintList(csl); 
+2

come 'getResources()' è deprecato, è ora 'ContextCompat.getColor (this, R.color.colorname);' o 'ContextCompat.getColor (getActivity(), R.color.colorname);' per l'uso in un Frammento – iBobb

+0

Per chiarire per altri lettori, 'new int [0]' (come elemento nella lista del primo parametro) è una matrice di lunghezza zero e rappresenta l'impostazione del colore predefinito. Qui è l'unico elemento, il che significa che la tinta viene applicata agli * all * stati del pulsante. Questo è equivalente a 'new int [] {}' visto nella risposta di Roger Alien. – ToolmakerSteve

8

A volte questo sarà sufficiente:

int colorInt = getResources().getColor(R.color.ColorVerificaLunes); 
ColorStateList csl = ColorStateList.valueOf(colorInt); 
1

La mia classe Builder per creare ColorStateList

private class ColorStateListBuilder { 
    List<Integer> colors = new ArrayList<>(); 
    List<int[]> states = new ArrayList<>(); 

    public ColorStateListBuilder addState(int[] state, int color) { 
     states.add(state); 
     colors.add(color); 
     return this; 
    } 

    public ColorStateList build() { 
     return new ColorStateList(convertToTwoDimensionalIntArray(states), 
       convertToIntArray(colors)); 
    } 

    private int[][] convertToTwoDimensionalIntArray(List<int[]> integers) { 
     int[][] result = new int[integers.size()][1]; 
     Iterator<int[]> iterator = integers.iterator(); 
     for (int i = 0; iterator.hasNext(); i++) { 
      result[i] = iterator.next(); 
     } 
     return result; 
    } 

    private int[] convertToIntArray(List<Integer> integers) { 
     int[] result = new int[integers.size()]; 
     Iterator<Integer> iterator = integers.iterator(); 
     for (int i = 0; iterator.hasNext(); i++) { 
      result[i] = iterator.next(); 
     } 
     return result; 
    } 
} 

Esempio Utilizzando

ColorStateListBuilder builder = new ColorStateListBuilder(); 
builder.addState(new int[] { android.R.attr.state_pressed }, ContextCompat.getColor(this, colorRes)) 
     .addState(new int[] { android.R.attr.state_selected }, Color.GREEN) 
     .addState(..., some color); 

if(// some condition){ 
     builder.addState(..., some color); 
} 
builder.addState(new int[] {}, colorNormal); // must add default state at last of all state 

ColorStateList stateList = builder.build(); // ColorStateList created here 

// textView.setTextColor(stateList); 
Problemi correlati