Modifier par programmation la valeur d'une ressource de couleur obtenus à partir de l'API de réponse

disons, sur mon appel API j'ai un paramètre qui s'appelle color . Est-il possible d'éditer ou de modifier un R.colors.color existant pour assigner la couleur à partir du résultat de L'API?

comme exemple:

je fais un appel à mon API et il retourne green , maintenant je veux charger mon application avec I. e (Vert Toolbar , Vert TextView couleur, etc.), est-ce possible?

ma première pensée fut:

créer un élément sur colors.xml appelé demo puis lui attribuer une couleur par défaut, puis utiliser cette demo couleur où je veux ( Button , TextView , etc.) Alors j'ai pensé qu'il serait possible de changer cette valeur programmatiquement avec le résultat de L'API pour que je n'aie pas besoin de créer un SharedPreferences ou quelque chose comme ça et pour éviter plus de code.

Comme @Y. S. m'a dit:

Malheureusement, vous devrez définir la couleur du texte ou afficher manuellement partout ... : (

je voudrais s'il y a une autre façon de le faire, puisque je ne sais pas combien de Activities mon projet contiendra, donc s'il y a une autre façon de le faire je suis heureux d'entendre d'autres suppositions.

EDIT

j'essaie la réponse de @Jared Rummler et peut-être que je fais quelque chose de mal... J'ai créé un simple Json et j'ai mis sur mon actif j'analyse le Json et je l'ai mis sur un GlobalConstant puis j'ai fait une"application simple".

tout D'abord j'ai un TextView et un Button qui contient le "your_special_color", et le retour de celui-ci je mets le GlobalConstant int comme suit:

case "your_special_color":                
            return GlobalConstant.color; 

alors ce que j'ai essayé est mon premier Activity a 1 TextView et 1 Button comme je l'ai dit avant et ils ont la couleur "your_special_color "que je ne veux pas changer, mais j'ai un Intent sur mon Button pour ouvrir l'autre Activity qui contient le même mais avec le GlobalConstant.color et il ne change pas.

j'ai essayé de faire ceci (ma deuxième activité):

public class Main2Activity extends AppCompatActivity {
private Res res;
@Override public Resources getResources() {
    if (res == null) {
        res = new Res(super.getResources());
    }
    return res;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
}

ai-je manqué quelque chose?

Oh.. J'ai compris que je faisais ça sur mon MainActivity2 ?

 Button btn = (Button)findViewById(R.id.button2);
 btn.setBackgroundColor(res.getColor(R.color.your_special_color));
60
demandé sur Community 2015-11-29 23:27:20

5 réponses

si vous jetez un coup d'oeil au document Accessing Resources , ce qu'il dit est que ...

une fois que vous avez fourni une ressource dans votre demande, vous pouvez l'appliquer en faisant référence à son ID de ressource. Tous les ID de ressources sont définis dans la classe R de votre projet, que l'outil aapt génère automatiquement.

en outre,

quand votre application est compilé , aapt génère la classe R , qui contient des ID de ressources pour toutes les ressources de votre res/ répertoire. Pour chaque type de Ressource, il existe une sous-classe R (pour exemple, R.drawable pour toutes les ressources mobilisables) , et pour chaque ressource de ce type, il y a un entier statique (par exemple, R.drawable.icon ). Cet entier est L'ID de la ressource que vous pouvez utiliser de récupérez votre ressource.

ce que cela signifie, essentiellement, est que pratiquement tout ce qui est tenu comme une ressource dans le répertoire res/ est compilé et référencé comme une constante immuable. C'est pour cette raison que les valeurs des éléments de ressources ne peuvent pas être modifiées programmatiquement/à l'exécution, car elles sont compilées . Par opposition aux variables locales / globales & SharedPreferences , les éléments de ressources sont représentés dans la mémoire du programme comme des objets fixes et immuables. Ils sont tenus dans une région spéciale de lecture seule de la mémoire du programme. À cet égard, voir également "change value of R. String Programmatically ".

Ce que vous peut n'est, pour éviter d'utiliser le même code à mille lieux de votre projet, créez une fonction commune qui modifie la valeur de la couleur dans la SharedPreferences et utilisez cette méthode partout. Je suis sûr que vous le saviez déjà, bien sûr.

pour réduire la quantité de code que vous devez ajouter au projet, il y a une alternative. J'ai déjà utilisé la bibliothèque de calligraphie qui m'a permis de fixer le style de police et la couleur tout au long de l'application. Cela peut être d'une bonne utilité pour vous, check it out ...

22
répondu Y.S. 2017-05-23 12:34:30

vous pouvez créer une classe qui étend Resources et outrepasser les méthodes getColor(int) et getColor(int, Theme) .

exemple:

couleurs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="your_special_color">#FF0099CC</color>
</resources>

Res.java

public class Res extends Resources {

    public Res(Resources original) {
        super(original.getAssets(), original.getDisplayMetrics(), original.getConfiguration());
    }

    @Override public int getColor(int id) throws NotFoundException {
        return getColor(id, null);
    }

    @Override public int getColor(int id, Theme theme) throws NotFoundException {
        switch (getResourceEntryName(id)) {
            case "your_special_color":
                // You can change the return value to an instance field that loads from SharedPreferences.
                return Color.RED; // used as an example. Change as needed.
            default:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    return super.getColor(id, theme);
                }
                return super.getColor(id);
        }
    }
}

BaseActivity.java

public class BaseActivity extends AppCompatActivity {

    ...

    private Res res;

    @Override public Resources getResources() {
        if (res == null) {
            res = new Res(super.getResources());
        }
        return res;
    }

    ...

}

C'est l'approche que j'ai utilisée dans l'une de mes applications, Vérification de la Racine . Si vous outrepassez getResources dans vos activités et dans la classe d'application principale, vous pouvez modifier le thème de manière programmatique (même si les thèmes sont immuables). Si vous le souhaitez, téléchargez l'application et voyez comment vous pouvez définir les couleurs primaires, accent et arrière-plan à partir des préférences.

48
répondu Jared Rummler 2015-12-09 11:52:37
La classe

R n'est pas censée être modifiée. Il contient simplement des références à vos ressources.

vous aurez besoin de le régler manuellement. Toutefois, pour réduire le fardeau de réglage manuellement, vous pouvez essayer d'utiliser des bibliothèques pour la sauvegarde des préférences, par exemple:

(liste complète des bibliothèques similaires https://android-arsenal.com/tag/75 )


en outre, vous pourriez vouloir penser à une autre façon d'appliquer les styles et les paramètres de passage - considérez que vous voudriez ajouter quelques autres paramètres comme la hauteur, la largeur, etc. Dans ce but, vous pouvez définir l'attribut personnalisé dans les thèmes.xml/les styles.XML:

<attr name="demoColor" format="reference|color" />

définissez ensuite les styles:

<style name="BaseActivity">
</style>
<style name="GreenActivity" parent="@style/BaseActivity">
    <item name="demoColor">#00cd00</item>
</style>
<style name="RedActivity" parent="@style/BaseActivity">
    <item name="demoColor">#ff0000</item>
</style>

puis utilisez cette couleur dans votre xml comme ceci:

... android:background="?demoColor" ...

et basculer entre GreenActivity et RedActivity styles dans Activity.onCreate :

setTheme(isGreenStyle() ? R.style.GreenActivity : R.style.RedActivity)
setContentView(...)

avec l'approche ci-dessus, vous serez en mesure de configurer facilement vos styles en xml et il devrait être moins de code et plus facile à remanier à l'avenir. (Vous aurez toujours besoin d'avoir une variable de préférence à enregistrer si vous avez des vert et rouge de style)


une autre façon, si vous voulez montrer des démos de votre application avec des couleurs différentes est d'utiliser des variantes de construction / saveurs pour charger votre application avec des couleurs et des styles différents (il est pour le temps de construction - pas d'exécution):

app/src/main/res/colors.xml

<resources>
    <color name="demoColor">#00cd00</color>
</resources>

app/src/buildVariant/res/colors.XML

<resources>
    <color name="demoColor">#ff0000</color>
</resources>

Maintenant, vous pouvez passer rapidement entre "main" et "buildVariant" dans le menu de construction de variantes et de lancer votre application avec différentes couleurs "Démo". De la même façon, vous pouvez personnaliser beaucoup d'autres attributs.

recherche de" construire des variantes "ici http://developer.android.com/tools/building/configuring-gradle.html

10
répondu GregoryK 2015-12-15 10:53:08

vous ne pouvez pas changer les ressources d'une application, ce sont toutes des constantes. À la place, vous pouvez enregistrer votre couleur dans SharedPrefences et utiliser la couleur à partir de là.

Voir Comment utiliser les SharedPreferences dans Android pour stocker, récupérer et modifier les valeurs .

si votre application a déjà une couleur R.Vert défini et vous voulez simplement y accéder en fonction de ce que L'API retourné vous utilisez:

int resourceID = getResources().getIdentifier("green", "color", getPackageName());
8
répondu Sourabh 2017-05-23 12:02:38

stocker des codes de couleur hexadécimaux dans des références partagées et ensuite utiliser la fonction parsecolor stocker vos hexadécimaux de couleurs en sessions comme une chaîne de caractères et chaque fois que vous voulez changer la couleur du bouton perticulaire ,textview..il suffit de récupérer ce code de couleur de la session et de l'utiliser comme

pour ex.

session.setString("white","#FFFFFF"); String colorname=session.getString("white");yourtextview.setBackgroundColor(Color.parseColor(colorname);

3
répondu Mayuresh Gawande 2015-12-09 12:34:58