8
votes

Comment obtenir de manière programmable une liste de couleurs d'un gradient sur Android

dans Android, je voudrais dessiner un Piechat avec un nombre dynamique de tartes. Chaque tarte doit avoir une couleur différente d'un gradient.

Par exemple, je voudrais avoir un gradient de brun clair au brun foncé. Si je dois dessiner cinq tartes, j'ai besoin de cinq voleurs du début à la fin de ce gradient.

Comment puis-je faire cela en Java avec le cadre Android?

J'ai trouvé Sortir que je peux créer un linéargradient pour une ligne, c'est-à-dire: xxx

mais je n'ai trouvé aucune fonction pour obtenir une couleur de cette ligne, c'est-à-dire: < Pré> xxx

Avez-vous des idées comment je peux obtenir cela?

Merci!


0 commentaires

3 Réponses :


18
votes

Vous ne pouvez pas obtenir ces valeurs directement du linéargradient. Le dégradé ne contient pas le dessin actuel. Pour obtenir ces valeurs, vous pouvez les peindre à une toile et tirer les couleurs de la toile, ou ce que je suggère de vouloir calculer les valeurs vous-même.

C'est un gradient linéaire répétitif en cinq étapes et vous avez le Valeurs RVB pour la première et la dernière couleur. Le reste est juste des mathématiques. Voici le pseudo code: xxx


1 commentaires

Merci pour cette idée simple et excellente!



7
votes

Une autre approche qui est un peu plus réutilisable (je semble heurter ce problème tout le temps). C'est un peu plus de code. Voici l'utilisation:

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


1 commentaires

Utile pour le calcul dynamique



1
votes

J'ai écrit la classe UTIL pour calculer le gradient de couleurs.

Via très, très simple Code Kotlin: P>

 class StepGradientUtil(private var colar1: Colar?, private var colar2: Colar?) {

    private var mSteps: Int = 0

    infix fun StepGradientUtil.gradient(f: () -> IntRange): IntArray {
        val result = f.invoke().map {
            it.colorStep()
        }.toIntArray()
        recycler()
        return result
    }

    infix fun Int.upTo(steps: Int): IntRange {
        mSteps = steps
        return (this until steps)
    }

    private fun recycler() {
        mSteps = 0
        colar1 = null
        colar2 = null
    }

    private fun Int.colorStep() = Color.rgb(
        (colar1!!.r * (mSteps - this) + colar2!!.r * this) / mSteps,
        (colar1!!.g * (mSteps - this) + colar2!!.g * this) / mSteps,
        (colar1!!.b * (mSteps - this) + colar2!!.b * this) / mSteps
    )
}

data class Colar(
    val r: Int,
    val g: Int,
    val b: Int
)

infix fun Colar.toColor(colar: Colar) = StepGradientUtil(colar1 = this, colar2 = colar)


0 commentaires