Страница 1 из 1

Использование тем (Dark or Light)

Добавлено: 06 май 2014, 17:12
CrazyManQ
Добрый день!

Пересмотрел всю данную ветку, но так и не нашел ответа для себя !!!
Ситуация следующая, в приложении требуется использовать 2-е темы : Dark или Light
Нарисованы темные кнопки и светлые.

Думаю решить данный вопрос путем использования стилей, но что то видать не догоняю.
сделал 2-а стиля
[syntax=java]
<style name="lightbuttonstyle">
<item name="android:background">@drawable/light_btn</item>
<item name="android:textcolor">#ff000000</item>
</style>
<style name="darkbuttonstyle">
<item name="android:background">@drawable/dark_btn</item>
<item name="android:textcolor">#ffffffff</item>
</style>
[/syntax]

затем создал атрибут ButtonAppearence который указываю в кнопке в style
а в стилях сделал такую штуку:
[syntax=java]
<style name="LigtTheme">
<item name="ButtonAppearence">@style/lightbuttonstyle</item>
</style>
<style name="DarkTheme">
<item name="ButtonAppearence">@style/darkbuttonstyle</item>
</style>
[/syntax]

По задумке при активном стиле DarkTheme - кнопки будут брать стиль darkbuttonstyle и наоборот ...
но как то этого не происходит.... :(

Вот и сижу и гуглю какойнить мануал по использованию этих стилей... может кто подскажет совет?
Возможно я чего то не написал или написал не так как хотел выразиться, спрашивайте!

Re: Использование тем (Dark or Light)

Добавлено: 06 май 2014, 21:49
RGLab
по поводу стилей можно попробовать начать отсюда
http://habrahabr.ru/post/133307/

Re: Использование тем (Dark or Light)

Добавлено: 07 май 2014, 09:03
klblk
вот тут я маленько расписывал работу с темами: viewtopic.php?t=1856&p=11213#p11213
правда там только для цветов и иконок, но вероятно через атрибуты можно задавать и стили для кнопок

Re: Использование тем (Dark or Light)

Добавлено: 07 май 2014, 15:20
CrazyManQ
Спасибо за ответы !!!
klblk писал(а):вот тут я маленько расписывал работу с темами: viewtopic.php?t=1856&p=11213#p11213
в точку - мысли прямо такие же!

В общем более или менее разобрался!
В итоге выявил свой косяк: в style= писал "@attr/ButtonAppearence", а надо "?attr/ButtonAppearence"

также помог хороший пост с примером:
http://www.androidengineer.com/2010/06/ ... tions.html

Re: Использование тем (Dark or Light)

Добавлено: 10 май 2014, 19:07
Viewer
klblk писал(а):вот тут я маленько расписывал работу с темами: viewtopic.php?t=1856&p=11213#p11213
правда там только для цветов и иконок, но вероятно через атрибуты можно задавать и стили для кнопок
В добавление к этому, еще можно задекларировать стили атрибутов там же в attrs.xml

[syntax=xml]<resources>
<declare-styleable name="my_styles">
<!-- Colors -->
<attr name="my_color" format="reference|color"/>
</declare-styleable>
</resources>[/syntax]


Тогда получать атрибуты для текущей темы в коде будет удобнее (для получения атрибутов стилей в xml все остается также)

[syntax=java]TypedArray a = obtainStyledAttributes(R.styleable.my_styles);
tv.setTextColor(a.getColor(R.styleable.my_styles_my_color, 0));
a.recycle();[/syntax]
метод obtainStyledAttributes() определенный в классе Context, позволяет получать атрибуты текущей темы Activity

Re: Использование тем (Dark or Light)

Добавлено: 13 май 2014, 17:08
CrazyManQ
А вот еще одна сложность!

Используя атрибуты стили успешно отрабатывают, но появилась задача поменять картинку под кнопкой в процессе работы программы - программно.
Т.е. к примеру кнопка может иметь 3 вида
1 - стандартное изображение
2 - кнопка в состоянии 1
3 - кнопка в состоянии 2
При запуске кнопка получает картинку стандартного изображения, в зависимости от выбранного стиля. Далее требуется по получению определенного флага изменить вид кнопки на один из 3-х вариантов (см. выше).
Если использовать setImageResource, то нужно указывать конкретный ресурс картинки, а как указать атрибут не понимаю, возможно нужно использовать другую команду а вот какую пока не нашел!

Есть 3 атрибута
[syntax=java]<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="btn_standard_App" format="reference" />
<attr name="btn_selector_orders_App" format="reference" />
<attr name="btn_selector_no_orders_App" format="reference" />
</resources>
[/syntax]

есть нужные селекторы картинок, типа такого:
[syntax=java]<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/dark_btn_standart_push" />
<item android:drawable="@drawable/dark_btn_standart" />
</selector>
[/syntax]

есть 2-а стиля :
[syntax=java]<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="style_btn_standard_dark">
<item name="android:background">@drawable/btn_standard_dark</item>
</style>
<style name="style_btn_selector_orders_dark">
<item name="android:background">@drawable/btn_selector_orders_dark</item>
</style>
<style name="style_btn_selector_no_orders_dark">
<item name="android:background">@drawable/btn_selector_no_orders_dark</item>
</style>

<style name="style_btn_standard">
<item name="android:background">@drawable/btn_standard</item>
</style>
<style name="style_btn_selector_orders">
<item name="android:background">@drawable/btn_selector_orders</item>
</style>
<style name="style_btn_selector_no_orders">
<item name="android:background">@drawable/btn_selector_no_orders</item>
</style>

<style name="LightFontTheme">
<item name="btn_standard_App">@style/style_btn_standard</item>
<item name="btn_selector_orders_App">@style/style_btn_selector_orders</item>
<item name="btn_selector_no_orders_App">@style/style_btn_selector_no_orders</item>
</style>

<style name="DarkFontTheme">
<item name="btn_standard_App">@style/style_btn_standard_dark</item>
<item name="btn_selector_orders_App">@style/style_btn_selector_orders_dark</item>
<item name="btn_selector_no_orders_App">@style/style_btn_selector_no_orders_dark</item>
</style>
</resources>
[/syntax]

вот сам примерный лайоут
[syntax=java]<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:gravity="center" android:padding="2.0dip" android:layout_width="fill_parent" android:layout_height="68.0dip"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView android:id="@id/ItemBackground" android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="?attr/btn_standard_App" android:scaleType="fitXY" />
</RelativeLayout>
[/syntax]


может есть какие то мысли ???

Re: Использование тем (Dark or Light)

Добавлено: 13 май 2014, 18:04
Viewer
CrazyManQ писал(а):А вот еще одна сложность!

Используя атрибуты стили успешно отрабатывают, но появилась задача поменять картинку под кнопкой в процессе работы программы - программно.


может есть какие то мысли ???
Обратите внимание на мой пост выше вашего.
для получения ID для setImageResource используйте a.getResourceId() (взамен a.getColor())

Непонятно только зачем вам нужно программно что-то делать, ведь все что вы хотите делается через разметку.
Для фона кнопки используйте селектор, в котором для каждого состояния для android:drawable= указывайте атрибуты стилей ?attr/

Re: Использование тем (Dark or Light)

Добавлено: 16 май 2014, 07:37
CrazyManQ
Блин написал целую петицию, нажал сохранить, а время сеанса завершилось :( и вся моя писанина коту под хвост !!!

Теперь кратко:
Сразу оговорюсь в качестве кнопок используется ImageView

- Использовать разметку не могу, т.е. использую только для нажата/не нажата.
Кнопки у меня могут иметь 4 состояния:
1 - стандартная кнопка
2 - стандартная выделенная кнопка
3 - активная кнопка
4 - выделенная активная кнопка
На форме вообще может находиться несколько кнопок,
при запуске программы все кнопки имеют стандартный вид, затем программа запрашивает данные по каждой кнопке и в соответствии со статусом меняет их внешний вид!
Также кнопка может поменять свой вид при долгом нажатии на нее (2,4 состояния)

Теперь по коду, вот примерно
[syntax=java]
private ImageView mBackground;
...
this.mBackground = ((ImageView) findViewById(R.id.MyItemBackground)); // ссылка на ImageView
try {
// пробовал так:
TypedArray a = getTheme().obtainStyledAttributes(new int[] {R.attr.btn_selector_no_orders_App});
// и пробовал так
TypedArray a = obtainStyledAttributes(R.styleable.my_styles);

// Эту часть не изменял
this.mBackground.setImageResource(a.getResourceId(R.styleable.my_styles_btn_selector_no_orders_App, 0));
a.recycle();
// вот так было раньше (используется прямая ссылка на drawable) - работает!
//this.mBackground.setImageResource(R.drawable.btn_selector_orders_active);//
} catch (Exception e) {
Log.e(LOG_TAG,e.getMessage());
}
[/syntax]

В общем без Try выскакивает ошибка и приложение падает... , с Try в журнал не попадает никакой инфы, но и ничего не происходит! :(

Пока что временное решение использовать Switch при прорисовке кнопок на разные темы

Для обозначения картинки используется функция defineBackgroundResIdByState()
this.mBackground.setImageResource(defineBackgroundResIdByState());

в котором сделал следующее:
[syntax=java]
{
int i = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getInt("Def_Theme", 0);
switch (i)
{
default:
return;
case 0:
// Light Theme
return LightResID;
case 1:
// Dark Theme
return DarkResID;
}
}
[/syntax]
LigthResID и DarkResID - соответственно функции где определяются ID картинок под разные статусы !!!

Re: Использование тем (Dark or Light)

Добавлено: 16 май 2014, 20:12
Viewer
Кнопки у меня могут иметь 4 состояния:
1 - стандартная кнопка
2 - стандартная выделенная кнопка
3 - активная кнопка
4 - выделенная активная кнопка
Ну так и делайте селектор на 4 состояния
Если используются две темы, значит нужно делать два селектора для каждой темы отдельно, т.е. нужно иметь по 4 набора картинок для каждой из тем:
btn_background_dark.xml
[syntax=xml]<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/btn_img_activated_selected_dark" android:state_activated="true" android:state_selected="true"></item>
<item android:drawable="@drawable/btn_img_selected_dark" android:state_selected="true"></item>
<item android:drawable="@drawable/btn_img_activated_dark" android:state_activated="true"></item>
<item android:drawable="@drawable/btn_img_dark"></item>

</selector>[/syntax]
btn_background_ligth.xml
[syntax=xml]<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/btn_img_activated_selected_ligth" android:state_activated="true" android:state_selected="true"></item>
<item android:drawable="@drawable/btn_img_selected_ligth" android:state_selected="true"></item>
<item android:drawable="@drawable/btn_img_activated_ligth" android:state_activated="true"></item>
<item android:drawable="@drawable/btn_img_ligth"></item>

</selector>[/syntax]

В файле styles.xml формируете две темы
[syntax=xml] <style name="AppTheme_Dark" parent="@style/Theme.AppCompat">
<item name="btn_background">@drawable/btn_background_dark</item>
</style>
<style name="AppTheme_Light" parent="@style/Theme.AppCompat.Light">
<item name="btn_background">@drawable/btn_background_ligth</item>
</style>[/syntax]
(В данном примере темы наследуются от Theme.AppCompat и Theme.AppCompat.Light из библиотеки совместимости v7 чисто для примера, если вы не используете ActionBar из этой библиотеки, нужно наследоваться от любых других базовых тем Android.)


в файле atrrs.xml создаете ссылку на атрибут
<attr name="btn_background" format="reference"></attr>

Ну и, наконец, в разметке layout-а для своей кнопки нужно указать
android:src="?attr/btn_background"

Теперь для выбора темы в коде нужно использовать в onCreate() метод:
setTheme(R.style.AppTheme_Light); или setTheme(R.style.AppTheme_Dark); в зависимости от настроек.
(Этот метод нужно вызывать до setContentView()!!)

И все, ничего не нужно делать в коде, для смены состояний можно сделать триггеры, к примеру вот так:
[syntax=java] ImageButton ib = (ImageButton) findViewById(R.id.imageButton1);
ib.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
v.setSelected(!v.isSelected());

}
});
ib.setOnLongClickListener(new OnLongClickListener() {

@Override
public boolean onLongClick(View v) {
v.setActivated(!v.isActivated());

return true;
}
});[/syntax]
По одиночному клику будет меняться state_selected, а по длинному клику state_activated
Это так, для примера, можете реализовать любое поведение, которое вам нужно.

На мой взгляд, все достаточно просто, не понимаю зачем изобретать велосипеды и подменять без необходимости стандартный функционал API Android? Google уже все продумал за нас ;)