Android - 如何动态更改 SwitchPreference 开关的 thumb/track 颜色
Android - How to dynamically change the thumb/track color of a SwitchPreference's switch
到目前为止,我只能在文本上更改 setSpan()
首选项的 summary/title 文本颜色,但我找不到任何可以更改 [=] 中 Switch 颜色的内容13=],我考虑了几个计划,包括设置自定义布局,或为首选项设置自定义适配器,但我还不清楚如何实现它们,因此,您的帮助将不胜感激。
PS:我考虑过简单地设置一个自定义布局,但这对我来说行不通,因为我需要在应用程序 运行 时更改 SwitchPreference
的颜色],用户可以为开关设置自定义颜色,因此主题在这种情况下也不起作用。
好的,我自己找到了解决方案:
创建自定义 SwitchPreference class,然后将其应用于您获得的所有 SwitchPreference 小部件,class 如下所示:
class ColorSwitchPreference extends SwitchPreference {
Switch aSwitch;
SharedPreferences sharedPreferences;
public ColorSwitchPreference(Context context){
super(context);
}
public ColorSwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ColorSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ColorSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
aSwitch = findSwitchInChildViews((ViewGroup) view);
if (aSwitch!=null) {
//do change color here
changeColor(aSwitch.isChecked(),aSwitch.isEnabled());
aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
changeColor(isChecked, aSwitch.isEnabled());
}
});
}
}
private void changeColor(boolean checked, boolean enabled){
try {
sharedPreferences = getContext().getSharedPreferences("settings_data",MODE_PRIVATE);
//apply the colors here
int thumbCheckedColor = sharedPreferences.getInt("theme_color_key",Color.parseColor("#3F51B5"));
int thumbUncheckedColor = Color.parseColor("#ECECEC");
int trackCheckedColor = sharedPreferences.getInt("theme_color_key",Color.parseColor("#3F51B5"));
int trackUncheckedColor = Color.parseColor("#B9B9B9");
if(enabled){
aSwitch.getThumbDrawable().setColorFilter(checked ? thumbCheckedColor : thumbUncheckedColor, PorterDuff.Mode.MULTIPLY);
aSwitch.getTrackDrawable().setColorFilter(checked ? trackCheckedColor : trackUncheckedColor, PorterDuff.Mode.MULTIPLY);
}else {
aSwitch.getThumbDrawable().setColorFilter(Color.parseColor("#B9B9B9"), PorterDuff.Mode.MULTIPLY);
aSwitch.getTrackDrawable().setColorFilter(Color.parseColor("#E9E9E9"), PorterDuff.Mode.MULTIPLY);
}
}catch (NullPointerException e){
e.printStackTrace();
}
}
private Switch findSwitchInChildViews(ViewGroup view) {// find the Switch widget in the SwitchPreference
for (int i=0;i<view.getChildCount();i++) {
View thisChildview = view.getChildAt(i);
if (thisChildview instanceof Switch) {
return (Switch)thisChildview;
}
else if (thisChildview instanceof ViewGroup) {
Switch theSwitch = findSwitchInChildViews((ViewGroup) thisChildview);
if (theSwitch!=null) return theSwitch;
}
}
return null;
}
}
基本上,您使用 findSwitchInChildViews()
在 SwitchPreference 中获取 Switch 小部件,然后从那里更改颜色。
就是这样!这实际上是一个非常简单的方法,但我之前没有考虑过,希望这个 post 可以帮助将来的人避免我的挣扎。
(PS: 我从 here, changing Switch color from here 那里得到了找到 Switch 的代码,谢谢!)
到目前为止,我只能在文本上更改 setSpan()
首选项的 summary/title 文本颜色,但我找不到任何可以更改 [=] 中 Switch 颜色的内容13=],我考虑了几个计划,包括设置自定义布局,或为首选项设置自定义适配器,但我还不清楚如何实现它们,因此,您的帮助将不胜感激。
PS:我考虑过简单地设置一个自定义布局,但这对我来说行不通,因为我需要在应用程序 运行 时更改 SwitchPreference
的颜色],用户可以为开关设置自定义颜色,因此主题在这种情况下也不起作用。
好的,我自己找到了解决方案:
创建自定义 SwitchPreference class,然后将其应用于您获得的所有 SwitchPreference 小部件,class 如下所示:
class ColorSwitchPreference extends SwitchPreference {
Switch aSwitch;
SharedPreferences sharedPreferences;
public ColorSwitchPreference(Context context){
super(context);
}
public ColorSwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ColorSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ColorSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
aSwitch = findSwitchInChildViews((ViewGroup) view);
if (aSwitch!=null) {
//do change color here
changeColor(aSwitch.isChecked(),aSwitch.isEnabled());
aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
changeColor(isChecked, aSwitch.isEnabled());
}
});
}
}
private void changeColor(boolean checked, boolean enabled){
try {
sharedPreferences = getContext().getSharedPreferences("settings_data",MODE_PRIVATE);
//apply the colors here
int thumbCheckedColor = sharedPreferences.getInt("theme_color_key",Color.parseColor("#3F51B5"));
int thumbUncheckedColor = Color.parseColor("#ECECEC");
int trackCheckedColor = sharedPreferences.getInt("theme_color_key",Color.parseColor("#3F51B5"));
int trackUncheckedColor = Color.parseColor("#B9B9B9");
if(enabled){
aSwitch.getThumbDrawable().setColorFilter(checked ? thumbCheckedColor : thumbUncheckedColor, PorterDuff.Mode.MULTIPLY);
aSwitch.getTrackDrawable().setColorFilter(checked ? trackCheckedColor : trackUncheckedColor, PorterDuff.Mode.MULTIPLY);
}else {
aSwitch.getThumbDrawable().setColorFilter(Color.parseColor("#B9B9B9"), PorterDuff.Mode.MULTIPLY);
aSwitch.getTrackDrawable().setColorFilter(Color.parseColor("#E9E9E9"), PorterDuff.Mode.MULTIPLY);
}
}catch (NullPointerException e){
e.printStackTrace();
}
}
private Switch findSwitchInChildViews(ViewGroup view) {// find the Switch widget in the SwitchPreference
for (int i=0;i<view.getChildCount();i++) {
View thisChildview = view.getChildAt(i);
if (thisChildview instanceof Switch) {
return (Switch)thisChildview;
}
else if (thisChildview instanceof ViewGroup) {
Switch theSwitch = findSwitchInChildViews((ViewGroup) thisChildview);
if (theSwitch!=null) return theSwitch;
}
}
return null;
}
}
基本上,您使用 findSwitchInChildViews()
在 SwitchPreference 中获取 Switch 小部件,然后从那里更改颜色。
就是这样!这实际上是一个非常简单的方法,但我之前没有考虑过,希望这个 post 可以帮助将来的人避免我的挣扎。
(PS: 我从 here, changing Switch color from here 那里得到了找到 Switch 的代码,谢谢!)