2011-10-15 5 views
7

in Android Vorrei disegnare un PieChart con un numero dinamico di torte. Ogni torta dovrebbe avere un colore diverso da una sfumatura.Come ottenere a livello di programmazione un elenco di colori da un gradiente su Android

Ad esempio, mi piacerebbe avere un gradiente dal marrone chiaro al marrone scuro. Se devo disegnare cinque torte, ho bisogno di cinque volori dall'inizio alla fine di questo gradiente.

Come posso farlo in Java con il framework Android?

ho scoperto che posso creare un linearGradient per una linea, vale a dire:

LinearGradient lg = new LinearGradient(1, 1, 5, 5, toRGB("lightbrown"), toRGB("darkbrown"), TileMode.REPEAT); 

ma non ho trovato alcuna funzione per ottenere un colore da questa linea, vale a dire:

// for the five needed RGB colors from the gradient line 
lg.getRGBColor(1, 1); 
lg.getRGBColor(2, 2); 
lg.getRGBColor(3, 3); 
lg.getRGBColor(4, 4); 
lg.getRGBColor(5, 5); 

Hai qualche idea su come posso ottenere questo?

Grazie!

risposta

16

Non è possibile ottenere questi valori direttamente dal LinearGradient. Il gradiente non contiene il disegno reale. Per ottenere questi valori, puoi dipingerli su una tela e tirare fuori i colori dalla tela, o quello che suggerirei sarebbe di calcolare da solo i valori.

È una sfumatura lineare ripetuta in cinque passaggi e si dispone dei valori RGB per il primo e l'ultimo colore. Il resto è solo matematica. Ecco il codice pseudo:

int r1 = startColor.red; 
int g1 = startColor.green; 
int b1 = startColor.blue; 

int r2 = endColor.red; 
int g2 = endColor.green; 
int b2 = endColor.blue; 

int redStep = r2 - r1/4; 
int greenStep = g2 - g1/4; 
int blueStep = b2 - b1/4; 

firstColor = new Color(r1, g1, b1); 
secondColor = new Color(r1 + redStep, g1 + greenStep, b1 + blueStep); 
thirdColor = new Color(r1 + redStep * 2, g1 + greenStep * 2, b1 + blueStep * 2); 
fourthColor = new Color(r1 + redStep * 3, g1 + greenStep * 3, b1 + blueStep * 3); 
fifthColor = new Color(r1 + redStep * 4, g1 + greenStep * 4, b1 + blueStep * 4); 
+0

molto buona. Idea semplice e soluzione di lavoro! Grazie – treimy

+0

Grazie per questa semplice e grande idea! – Gatekeeper

3

Un altro approccio che è un po 'più riutilizzabile (mi sembra di imbattersi in questo problema tutto il tempo). È un po 'più codice. Ecco l'utilizzo:

int[] colors = {toRGB("lightbrown"), toRGB("darkbrown")};//assuming toRGB : String -> Int 
    float[] positions = {1, 5}; 
    getColorFromGradient(colors, positions, 1) 
    //... 
    getColorFromGradient(colors, positions, 5) 

Funzioni di supporto

public static int getColorFromGradient(int[] colors, float[] positions, float v){ 

    if(colors.length == 0 || colors.length != positions.length){ 
     throw new IllegalArgumentException(); 
    } 

    if(colors.length == 1){ 
     return colors[0]; 
    } 

    if(v <= positions[0]) { 
     return colors[0]; 
    } 

    if(v >= positions[positions.length-1]) { 
     return colors[positions.length-1]; 
    } 

    for(int i = 1; i < positions.length; ++i){ 
     if(v <= positions[i]){ 
      float t = (v - positions[i-1])/(positions[i] - positions[i-1]); 
      return lerpColor(colors[i-1], colors[i], t); 
     } 
    } 

    //should never make it here 
    throw new RuntimeException(); 
} 

public static int lerpColor(int colorA, int colorB, float t){ 
    int alpha = (int)Math.floor(Color.alpha(colorA) * (1 - t) + Color.alpha(colorB) * t); 
    int red = (int)Math.floor(Color.red(colorA) * (1 - t) + Color.red(colorB) * t); 
    int green = (int)Math.floor(Color.green(colorA) * (1 - t) + Color.green(colorB) * t); 
    int blue = (int)Math.floor(Color.blue(colorA) * (1 - t) + Color.blue(colorB) * t); 

    return Color.argb(alpha, red, green, blue); 
} 
+0

utili per il calcolo dinamico – Godwin