Как изменить цвет дорожки SwitchCompat
Я попытался использовать следующую ссылку, чтобы изменить цвет SwitchCompat:
Как изменить цвет SwitchCompat
Обратите внимание на низкое ограничение в моем переключателе:
Но после изменения всех соответствующих значений цвета дорожка (более яркий серый) SwitchCompat остается прежней. Я не хочу менять внешний вид, кроме цвета. Большой палец в розовом, и я хочу, чтобы у трека был какой-то контраст. Я пропустил определение значения в моем styles.xml?
Я пробовал эти значения (случайные небелые цвета):
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/first</item>
<item name="colorPrimaryDark">@color/second</item>
<item name="colorAccent">@color/third</item>
...
<item name="colorControlActivated">@color/first</item>
<item name="colorControlHighlight">@color/first</item>
<item name="colorControlNormal">@color/second</item>
<item name="colorSwitchThumbNormal">@color/second</item>
<item name="colorButtonNormal">@color/second</item>
...>
8 ответов
У меня был такой же пробрем и я решил его.
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
<!-- Active thumb color & Active track color(30% transparency) -->
<item name="colorControlActivated">@color/theme</item>
<!-- Inactive thumb color -->
<item name="colorSwitchThumbNormal">@color/grey300</item>
<!-- Inactive track color(30% transparency) -->
<item name="android:colorForeground">@color/grey600</item>
...
</style>
Я прочитал код приложения и понял его.
android.support.v7.internal.widget.TintManager.java
private ColorStateList getSwitchTrackColorStateList() {
if (mSwitchTrackStateList == null) {
final int[][] states = new int[3][];
final int[] colors = new int[3];
int i = 0;
// Disabled state
states[i] = new int[] { -android.R.attr.state_enabled };
colors[i] = getThemeAttrColor(android.R.attr.colorForeground, 0.1f);
i++;
states[i] = new int[] { android.R.attr.state_checked };
colors[i] = getThemeAttrColor(R.attr.colorControlActivated, 0.3f);
i++;
// Default enabled state
states[i] = new int[0];
colors[i] = getThemeAttrColor(android.R.attr.colorForeground, 0.3f);
i++;
mSwitchTrackStateList = new ColorStateList(states, colors);
}
return mSwitchTrackStateList;
}
Ниже приведен способ AppCompat для программного изменения цвета дорожки и большого пальца для конкретного SwitchCompat. Для этого примера я жестко закодировал thumbColor
к красному. В идеале вы должны установить цвет через второй параметр метода.
Обратите внимание, что при проверке переключателя отображается пульсация. Цвет пульсации не будет изменен кодом ниже.
public static void setSwitchColor(SwitchCompat v) {
// thumb color of your choice
int thumbColor = Color.RED;
// trackColor is the thumbColor with 30% transparency (77)
int trackColor = Color.argb(77, Color.red(thumbColor), Color.green(thumbColor), Color.blue(thumbColor));
// setting the thumb color
DrawableCompat.setTintList(v.getThumbDrawable(), new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_checked},
new int[]{}
},
new int[]{
thumbColor,
Color.WHITE
}));
// setting the track color
DrawableCompat.setTintList(v.getTrackDrawable(), new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_checked},
new int[]{}
},
new int[]{
trackColor,
Color.parseColor("#4D000000") // full black with 30% transparency (4D)
}));
}
Если вы хотите оценить стоимость трека. вы можете использовать это решение.
трек selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/checked_color" android:state_checked="true" />
<item android:color="@color/checked_color" android:state_selected="true" />
<item android:color="@color/unchecked_color" android:state_checked="false" />
<item android:color="@color/unchecked_color" android:state_selected="false" />
где check_color и unchecked_color - это цвет вашего выбора.
styles.xml
<style name="mySwitchStyle" parent="@style/Widget.AppCompat.CompoundButton.Switch">
<!-- do here for additional costumization on thumb, track background,text appearance -->
</style>
<style name="mySwitchTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="switchStyle">@style/mySwitchStyle</item>
<item name="colorControlActivated">@color/red</item>
<item name="colorControlNormal">@color/colorAccent</item>
<item name="trackTint">@color/track_selector</item>
</style>
файл макета
<android.support.v7.widget.SwitchCompat
android:theme="@style/mySwitchTheme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
С MaterialSwitch
предоставляется Библиотекой компонентов материала.
- Использовать
materialThemeOverlay
, чтобы переопределить цвет приложения для коммутатора.
<style name="CustomWidget.MaterialComponents.CompoundButton.Switch" parent="Widget.MaterialComponents.CompoundButton.Switch">
<item name="materialThemeOverlay">@style/CustomCompoundButton_Switch</item>
</style>
<style name="CustomCompoundButton_Switch" >
<item name="colorSurface">@color/yellow</item>
<item name="colorOnSurface">@color/orange</item>
<item name="colorControlActivated">@color/blue</item>
</style>
А в макете:
<com.google.android.material.switchmaterial.SwitchMaterial
style="@style/Widget.MaterialComponents.CompoundButton.Switch"
../>
h ttps:https://stackru.com/images/69b208dc6a326ab8adcf1af67227d2ae4aa25194.png h ttps:https://stackru.com/images/43706a5c2a9541e057fa65d90605bc9cbb4395ba.png
- Использовать
style
атрибут:
<style name="CustomStyleWidget.MaterialComponents.CompoundButton.Switch"
parent="Widget.MaterialComponents.CompoundButton.Switch">
<item name="useMaterialThemeColors">false</item>
<item name="trackTint">@color/track_selector</item>
<item name="thumbTint">@color/thumb_selector</item>
</style>
с thumb_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@color/switchTrackDisable"/>
<item android:state_checked="true" android:color="@color/switchThumbActive" />
<item android:color="@color/switchThumbkNormal" />
</selector>
и track_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@color/switchTrackDisable"/>
<item android:state_checked="true" android:color="@color/switchTrackActive" />
<item android:color="@color/switchTrackNormal" />
</selector>
А в макете:
<com.google.android.material.switchmaterial.SwitchMaterial
style="@style/CustomStyleWidget.MaterialComponents.CompoundButton.Switch"
../>
Если вам нужно больше переключателей в нескольких цветах в одном действии, вы можете использовать это решение (на основе темы от @Konifar):
<style name="CustomSwitchTheme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<!-- Active thumb color & Active track color(30% transparency) -->
<item name="colorControlActivated">@color/custom</item>
<!-- Inactive thumb color -->
<item name="colorSwitchThumbNormal">#E0E0E0</item>
<!-- Inactive track color(30% transparency) -->
<item name="android:colorForeground">#757575</item>
</style>
где @color/custom
это цвет большого пальца, когда переключатель активирован.
Затем примените эту тему к вашему SwitchCompat следующим образом:
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/CustomSwitchTheme" />
Here is Switch Layout
-Adding theme to your switch to change the color of track.Check the style given below:-.
**Switch Compact**
<android.support.v7.widget.SwitchCompat
android:id="@+id/goOnlineBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:theme="@style/Switch_style/>
**Switch_style**
<style name="Switch_style" parent="Theme.AppCompat.Light">
<!-- active thumb & track color (30% transparency) -->
<item name="colorControlNormal">@android:color/white</item>
<item name="colorControlActivated">@android:color/blue</item>
<item name="colorSwitchThumbNormal">@android:color/white</item>
<item name="trackTint">@color/white</item>
</style>
Где trackTint изменит цвет вашего трека
Вот как разработчик может изменить нарисованный трек SwitchCompat:
Сначала в корневом макете напишите xmlns:SwitchCompat="http://schemas.android.com/apk/res-auto"
Затем:
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:thumb="@drawable/your_switch_thumb"
SwitchCompat:track="@drawable/your_switch_track_selector"
/>
где your_switch_track_selector может быть:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/switch_ios_track_on" android:state_checked="true" />
<item android:drawable="@drawable/switch_ios_track_off" android:state_checked="false" />
</selector>
1.switch_ios_track_on:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid android:color="#4EDA62" />
<corners android:radius="20dp" />
</shape>
2.switch_ios_track_off:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid android:color="#E3E3E3" />
<corners android:radius="20dp" />
</shape>
Просто и легко..
Просто используйте colorControlActivation, чтобы установить цвет дорожки и большого пальца SwitchCompat.
Если не установлено, цвет по умолчанию colorControlActivation будет использовать colorAccent. (из опыта, до сих пор не найти, где в исходном коде).
Исходный код изменился и не похож на @Ovidiu. Но все же спасибо ему, что сообщили мне найти ответ из исходного кода.
mThumbDrawable = a.getDrawable(R.styleable.SwitchCompat_android_thumb);
в конечном итоге вызовет следующий метод.
/frameworks/support/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
private ColorStateList createSwitchTrackColorStateList(Context context) {
final int[][] states = new int[3][];
final int[] colors = new int[3];
int i = 0;
// Disabled state
states[i] = ThemeUtils.DISABLED_STATE_SET;
colors[i] = getThemeAttrColor(context, android.R.attr.colorForeground, 0.1f);
i++;
states[i] = ThemeUtils.CHECKED_STATE_SET;
colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated, 0.3f);
i++;
// Default enabled state
states[i] = ThemeUtils.EMPTY_STATE_SET;
colors[i] = getThemeAttrColor(context, android.R.attr.colorForeground, 0.3f);
i++;
return new ColorStateList(states, colors);
}
private ColorStateList createSwitchThumbColorStateList(Context context) {
final int[][] states = new int[3][];
final int[] colors = new int[3];
int i = 0;
final ColorStateList thumbColor = getThemeAttrColorStateList(context,
R.attr.colorSwitchThumbNormal);
if (thumbColor != null && thumbColor.isStateful()) {
// If colorSwitchThumbNormal is a valid ColorStateList, extract the default and
// disabled colors from it
// Disabled state
states[i] = ThemeUtils.DISABLED_STATE_SET;
colors[i] = thumbColor.getColorForState(states[i], 0);
i++;
states[i] = ThemeUtils.CHECKED_STATE_SET;
colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated);
i++;
// Default enabled state
states[i] = ThemeUtils.EMPTY_STATE_SET;
colors[i] = thumbColor.getDefaultColor();
i++;
} else {
// Else we'll use an approximation using the default disabled alpha
// Disabled state
states[i] = ThemeUtils.DISABLED_STATE_SET;
colors[i] = getDisabledThemeAttrColor(context, R.attr.colorSwitchThumbNormal);
i++;
states[i] = ThemeUtils.CHECKED_STATE_SET;
colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated);
i++;
// Default enabled state
states[i] = ThemeUtils.EMPTY_STATE_SET;
colors[i] = getThemeAttrColor(context, R.attr.colorSwitchThumbNormal);
i++;
}
return new ColorStateList(states, colors);
}
У меня была такая же проблема. Окончательно решил это программно с этим кодом Kotlin
fun tintSwitchButton(sw: SwitchCompat, resolvedColor: Int) {
val states = arrayOf(
intArrayOf(-android.R.attr.state_pressed),
intArrayOf(android.R.attr.state_pressed)
)
DrawableCompat.setTintList(sw?.trackDrawable, ColorStateList(
states,
intArrayOf(resolvedColor, resolvedColor)
))
DrawableCompat.setTintList(sw?.thumbDrawable, ColorStateList(
states,
intArrayOf(Color.WHITE, Color.WHITE)
))
}
И вызов функции
tintSwitchButton(switchCompat, Color.rgb(214, 0, 0))
Вы также можете создать функцию расширения:
fun SwitchCompat.tint(resolvedColor: Int) {
val states = arrayOf(
intArrayOf(-android.R.attr.state_pressed),
intArrayOf(android.R.attr.state_pressed)
)
DrawableCompat.setTintList(trackDrawable, ColorStateList(
states,
intArrayOf(resolvedColor, resolvedColor)
))
DrawableCompat.setTintList(thumbDrawable, ColorStateList(
states,
intArrayOf(Color.WHITE, Color.WHITE)
))
}
Так что звонок будет проще
switchCompat.tint(Color.rgb(214,0,0))
SwitchCompat - это виджет Material Design. когда моя деятельность расширяется AppCompatActivity и работает android:theme="@style/mySwitch".