- PVSM.RU - https://www.pvsm.ru -
В предыдущей статье [1] мы рассмотрели как использовать темы и стили на уровне кода, на примере кастомной view. В этой статье давайте разберем несколько способов стилизации стандартного ui элемента, а в частности SwitchCompat.
Введение [2]
Новый стиль для switchStyle [3]
Стиль в верстке [4]
Стиль в теме. Тема назначается через Manifest. [5]
Стиль в теме. Тема назначается программно. [6]
Другие View [7]
Не всегда оформление по умолчанию стандартного UI элемента устраивает дизайнера. Давайте разберем, как поменять внешний вид элемента на примере SwitchCompat.
Для решения задачи нам нужно:
Назначить стиль SwitchCompat можно несколькими способами, например:
В ресурсах создадим новый стиль MySwitchStyle, наследуем оформление от Widget.AppCompat.CompoundButton.Switch, задав parent. Можно и не наследовать, но тогда придется указать все значения, даже которые мы не планируем менять.
<style name="MySwitchStyle" parent = "Widget.AppCompat.CompoundButton.Switch">
</style>
Чтобы что-то изменить, надо переопределить требуемые атрибуты. Атрибуты можно посмотреть в документации. [8]
В документации видим несколько атрибутов. Они указаны в виде, как если бы мы обращались к ним в коде (например, вот так R.styleable.SwitchCompat_android_thumb). Я расшифрую только часть из них, чтобы не было сомнений. Назначение остальных несложно понять из документации.
В коде | В xml |
SwitchCompat_android_thumb | android:thumb |
SwitchCompat_thumbTint | thumbTint |
SwitchCompat_track | track |
SwitchCompat_trackTint | trackTint |
В качестве примера изменим цвет thumb (кружочка) — пусть во включенном состоянии он будет оранжевым, в выключенном — зеленым. Некрасиво, но наглядно.
Нам понадобится селектор в папке color наших ресурсов. Файл selector_switch_thumb.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:color = "@android:color/holo_orange_dark"/>
<item android:color="@android:color/holo_green_light"/>
</selector>
Теперь зададим атрибут thumbTint в нашем стиле.
<style name="MySwitchStyle" parent = "Widget.AppCompat.CompoundButton.Switch">
<item name="thumbTint">@color/selector_switch_thumb</item>
</style>
Теперь все SwitchCompat, получившие каким-то образом стиль MySwitchStyle, будут выглядеть по-новому.
Самый тривиальный и негибкий способ.
<androidx.appcompat.widget.SwitchCompat
android:text="Themed switch"
style="@style/MySwitchStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Создаем тему AppTheme и задаем значение атрибуту switchStyle. Значением является наш стиль MySwitchStyle.
<resources>
<style name="CustomTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<!-- Задаем значение атрибуту switchStyle -->
<item name="switchStyle">@style/MySwitchStyle</item>
</style>
</resources>
Тема может быть указана в манифесте для всего приложения
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/CustomTheme"><!-- Тема для всего приложения -->
</application>
Или для конкретной активити
<activity
android:name=".MainActivity"
android:theme="@style/CustomTheme"><!-- Тема для активити -->
</activity>
Теперь все SwitchCompat будут иметь новый внешний вид. Без изменения в верстке.
Для того, чтобы установить тему для активити программно, нужно вызвать метод активити setTheme(themeResId).
Давайте менять тему активити в зависимости от состояния Switch.
class MainActivity : AppCompatActivity() {
private const val KEY_CUSTOM_THEME_CHECKED = "KEY_CUSTOM_THEME_CHECKED"
class MainActivity : AppCompatActivity() {
private val preference by lazy {
PreferenceManager.getDefaultSharedPreferences(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
val isCustomThemeChecked = preference.getBoolean(
KEY_CUSTOM_THEME_CHECKED,
true
)
if (isCustomThemeChecked) {
setTheme(R.style.CustomTheme)
} else {
setTheme(R.style.StandardTheme)
}
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
customThemeCheckbox.isChecked = isCustomThemeChecked
customThemeCheckbox.setOnCheckedChangeListener { _, isChecked ->
preference.edit()
.putBoolean(KEY_CUSTOM_THEME_CHECKED, isChecked)
.apply()
recreate()
}
}
}
Результат
<resources>
<style name="CustomTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="switchStyle">@style/MySwitchStyle</item>
</style>
<style name="StandardTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="MySwitchStyle" parent="Widget.AppCompat.CompoundButton.Switch">
<item name="thumbTint">@color/selector_switch_thumb</item>
</style>
</resources>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<CheckBox
android:text="CustomTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:saveEnabled="false"
android:id="@+id/customThemeCheckbox"/>
<androidx.appcompat.widget.SwitchCompat
android:text="Themed switch"
android:layout_marginTop="56dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/themedSwitch"/>
</LinearLayout>
Чтобы переопределить стиль для SwitсhView для всего приложения, мы переопределили значение атрибута switchStyle, можно догадаться, что такие атрибуты есть и для других View.
Например:
Как их искать? Я просто смотрю исходники, через Android Studio.
Заходим в тему, зажимаем ctrl, кликаем на родителе нашей темы. Смотрим, как описывают тему ребята из Google. Смотрим, какой атрибут определяется и от какого стиля можно отнаследоваться. Пользуемся.
Кусок из темы Base.V7.Theme.AppCompat.Light.
<item name="editTextStyle">@style/Widget.AppCompat.EditText</item>
<item name="checkboxStyle">@style/Widget.AppCompat.CompoundButton.CheckBox</item>
<item name="radioButtonStyle">
@style/Widget.AppCompat.CompoundButton.RadioButton
</item>
<item name="buttonStyle">@style/Widget.AppCompat.Button</item>
developer.android.com/guide/topics/ui/look-and-feel/themes [9]
developer.android.com/reference/android/support/v7/widget/SwitchCompat.html#xml-attributes [8]
P.S.
Статья не претендует на полный справочник. Код умышленно сокращен. Я ставил задачу дать общее понимание — как это работает и зачем это нужно. Дальше все легко ищется в документации и в стандартных ресурсах.
Автор: Дмитрий Берендеев
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android-development/320945
Ссылки в тексте:
[1] предыдущей статье: https://habr.com/ru/post/453812/
[2] Введение: #introduction
[3] Новый стиль для switchStyle: #new-style
[4] Стиль в верстке: #style-in-layout
[5] Стиль в теме. Тема назначается через Manifest.: #style-in-theme-manifest
[6] Стиль в теме. Тема назначается программно.: #style-in-theme-programmatically
[7] Другие View: #other-view
[8] документации.: https://developer.android.com/reference/android/support/v7/widget/SwitchCompat.html#xml-attributes
[9] developer.android.com/guide/topics/ui/look-and-feel/themes: https://developer.android.com/guide/topics/ui/look-and-feel/themes
[10] Источник: https://habr.com/ru/post/456178/?utm_source=habrahabr&utm_medium=rss&utm_campaign=456178
Нажмите здесь для печати.