Changer la couleur du texte de NumberPicker
j'ai regardé la plupart des fils sur ceci et aucun n'a fourni une réponse qui fonctionne. Le style de L'Engourdisseur ne fonctionne pas (selon ce fil: engourdissement textColour )
définir l'attribut style sur le numéroteur à un style qui a un élément de couleur n'a pas d'effet non plus. La définition de l'attribut textColor sur le XML numberPicker ne fait rien non plus.
ce que j'ai de plus proche c'est d'utiliser le numberPicker pour lancer son getChildAt() dans un texte édité et ensuite faire setColor () sur ce texte édité, mais cela ne change la couleur de l'enfant qu'une fois lors de l'initialisation et ensuite à chaque fois qu'il est sélectionné à partir de là; pas ce que je cherche non plus.
de l'aide? Merci
8 réponses
Ce code devrait résoudre votre problème. Le problème que vous rencontrez est parce que pendant la construction de NumberPicker il capture le textColor EditText et assigne à une peinture de sorte qu'il peut dessiner les nombres au-dessus et au-dessous du texte d'édition avec la même couleur.
import java.lang.reflect.Field;
public static boolean setNumberPickerTextColor(NumberPicker numberPicker, int color)
{
final int count = numberPicker.getChildCount();
for(int i = 0; i < count; i++){
View child = numberPicker.getChildAt(i);
if(child instanceof EditText){
try{
Field selectorWheelPaintField = numberPicker.getClass()
.getDeclaredField("mSelectorWheelPaint");
selectorWheelPaintField.setAccessible(true);
((Paint)selectorWheelPaintField.get(numberPicker)).setColor(color);
((EditText)child).setTextColor(color);
numberPicker.invalidate();
return true;
}
catch(NoSuchFieldException e){
Log.w("setNumberPickerTextColor", e);
}
catch(IllegalAccessException e){
Log.w("setNumberPickerTextColor", e);
}
catch(IllegalArgumentException e){
Log.w("setNumberPickerTextColor", e);
}
}
}
return false;
}
la solution que j'ai essayé et travaillé pour moi est:
dans styles.ajouter:
<style name="AppTheme.Picker" parent="Theme.AppCompat.Light.NoActionBar" >
<item name="android:textColorPrimary">@android:color/black</item>
</style>
alors utilisez - le comme ceci dans votre mise en page:
<NumberPicker
android:id="@+id/dialogPicker"
android:theme="@style/AppTheme.Picker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp" />
Je ne sais pas pourquoi vous devriez plonger dans L'API Java Reflection pour cela. Ses un style simple de la matière. L'attribut que vous devez outrepasser est: textColorPrimary
.
<style name="AppTheme" parent="@android:style/Theme.Holo.Light">
....
<item name="android:textColorPrimary">#ff0000</item>
</style>
si vous utilisez le TimePicker
dans un Dialog
, remplacez android:textColorPrimary
dans le thème de dialogue.
c'est à peu près tout.
informations supplémentaires:
Voici une perspicace commentaire de Yoann Hercouet :
cette solution ne change pas seulement la couleur sur le NumberPicker, il est un changement global qui aura un impact sur beaucoup de composants
c'est exact, mais il ignore les possibilités que je fais allusion. De plus, global
implique un impact à l'échelle du PPA. Ce thème peut être limité à l'activité-champ d'application en appliquant ce thème uniquement aux activités qui contiennent le NumberPicker
." . Mais, je suis d'accord, cela peut encore être trop corrosif .
l'idée ici est d'injecter textColorPrimary=INTENDED_COLOR
dans le thème qui sera vu par NumberPicker
. Il existe plusieurs façons d'atteindre cet objectif. Voici un chemin:
Définir un nu-os style res/values/styles.xml
:
<style name="NumberPickerTextColorStyle">
<item name="android:textColorPrimary">@color/intended_color</item>
</style>
maintenant, créer une coutume NumberPicker
:
public class ThemedNumberPicker extends NumberPicker {
public ThemedNumberPicker(Context context) {
this(context, null);
}
public ThemedNumberPicker(Context context, AttributeSet attrs) {
// wrap the current context in the style we defined before
super(new ContextThemeWrapper(context, R.style.NumberPickerTextColorStyle), attrs);
}
}
enfin, utilisez ThemedNumberPicker
dans votre mise en page(s):
<package.name.ThemedNumberPicker
android:id="@+id/numberPicker"
....
....
.... />
Nous avons réussi à contenir l'impact que textColorPrimary=INTENDED_COLOR
a sur notre application.
ce n'est bien sûr qu'une option. Par exemple, si vous gonfliez une mise en page contenant un NumberPicker
, vous pourriez utiliser:
// In this case, the layout contains <NumberPicker... />, not <ThemedNumberPicker... />
LayoutInflater.from(new ContextThemeWrapper(context, R.style.NumberPickerTextColorStyle))
.inflate(R.layout.number_picker_layout, ...);
voici un extrait de Xamarin de la réponse ci-dessus avec TextSize et TextStyle Bold
public static bool SetNumberPickerTextColorAndSize(NumberPicker numberPicker, Color color, ComplexUnitType complexUnitType, float textSize, TypefaceStyle style)
{
int count = numberPicker.ChildCount;
for (int i = 0; i < count; i++)
{
View child = numberPicker.GetChildAt(i);
if (child.GetType() == typeof(EditText))
{
try
{
Field selectorWheelPaintField = numberPicker.Class
.GetDeclaredField("mSelectorWheelPaint");
selectorWheelPaintField.Accessible = true;
EditText editText = (EditText) child;
editText.SetTextSize(complexUnitType, textSize);
editText.SetTypeface(editText.Typeface, style);
editText.SetTextColor(color);
Paint paint = (Paint) selectorWheelPaintField.Get(numberPicker);
paint.TextSize = TypedValue.ApplyDimension(complexUnitType, textSize, numberPicker.Resources.DisplayMetrics);
paint.Color = color;
paint.SetTypeface(editText.Typeface);
numberPicker.Invalidate();
return true;
}
catch (NoSuchFieldException e)
{
Log.Warn("setNumberPickerTextColor", e);
}
catch (IllegalAccessException e)
{
Log.Warn("setNumberPickerTextColor", e);
}
catch (IllegalArgumentException e)
{
Log.Warn("setNumberPickerTextColor", e);
}
}
}
return false;
}
la réponse acceptée est trop compliquée. Une approche beaucoup plus simple qui a fonctionné pour moi était de passer outre l'attribut textColorPrimary
du thème que j'utilisais.
<style name="Theme.MyTheme" parent="@android:style/Theme.Holo.NoActionBar.Fullscreen" >
<item name="android:textColorPrimary">#000000</item>
</style>
Il a fait le travail très bien!
au lieu de changer chaque couleur de texte à la couleur que vous voulez, mieux vaut juste changer toute la couleur editText. NumberPicker a en fait un Édittext enfant qui affiche les nombres.
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
<!-- Change edit color here. -->
<item name="android:editTextColor">#000000</item>
</style>
ça a marché pour moi. Et bien que j'ai du texte blanc sur les boutons, ils n'ont pas changé.
j'ai pris la solution de @Andreas Merz et mis à jour son code. La façon dont les choses ont été attribuées et les fonctions signatures/appels qu'il a utilisés n'ont pas été trouvés. J'utilise min API 19
. Voici le code qui a fonctionné pour moi.
/**
* Based on https://stackoverflow.com/a/26657169/2313889
* @param picker
* @param color
* @param unit
* @param textSize
* @param typeface
* @return
*/
private void formatNumberPickerText(NumberPicker picker, int color,
int unit, float textSize,
Typeface typeface) {
int count = picker.getChildCount();
for (int i = 0; i < count; i++) {
View child = picker.getChildAt(i);
if (child instanceof EditText) {
try {
Class clazz = picker.getClass();
Field field = clazz.getDeclaredField("mSelectorWheelPaint");
field.setAccessible(true);
EditText editText = (EditText) child;
editText.setTextSize(unit, textSize);
editText.setTypeface(typeface);
editText.setTextColor(color);
Paint paint = (Paint) field.get(picker);
paint.setTextSize(TypedValue.applyDimension(
unit, textSize, getResources().getDisplayMetrics()
));
paint.setColor(color);
paint.setTypeface(typeface);
picker.invalidate();
return;
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
}
}
C'est facile avec mon NumberPicker bibliothèque .
<com.github.tomeees.scrollpicker.ScrollPicker
...
app:textColor="..."
/>