Прикрепите пользовательский стиль CardView к теме

В моем приложении у меня есть две темы (светлые и темные), и я хочу, чтобы все мои CardView меняли свой цвет фона в зависимости от выбранной темы.

Я не хочу:

 <android.support.v7.widget.CardView style="@style/CardView.MyBlue" android:layout_width="200dp" android:layout_height="100dp" android:layout_gravity="center_horizontal"> 

Вышеприведенный код не является динамическим. Мне нужно, чтобы мои два стиля автоматически применялись в зависимости от того, выбрана ли светлая или темная тема.


То, что у меня сейчас, не работает:

 <style name="AppTheme.Light" parent="Theme.AppCompat.Light"> ... <item name="cardViewStyle">@style/CardViewStyle.Light</item> </style> <style name="AppTheme.Dark" parent="Theme.AppCompat"> ... <item name="cardViewStyle">@style/CardViewStyle.Dark</item> </style> <style name="CardViewStyle.Light" parent="CardView"> <item name="cardBackgroundColor">@color/cardview_dark_background</item> </style> <style name="CardViewStyle.Dark" parent="CardView"> <item name="cardBackgroundColor">@color/cardview_light_background</item> </style> 

Я где-то читал, что вы можете определить файл styleable.xml в /res/values/ для ввода слова cardViewStyle , поэтому я сделал это:

styleable.xml:

 <resources> <declare-styleable name="AppTheme"> <attr name="cardViewStyle" format="reference" /> </declare-styleable> </resources> 

Обновить

Аналогичный вопрос здесь и без ответа.

В styles.xml

 <resources> <attr format="reference" name="cardStyle"/> <style name="Light" parent="Theme.AppCompat.NoActionBar"> <item name="cardStyle">@style/CardView.Light</item> ... </style> <style name="Dark" parent="Theme.AppCompat.NoActionBar"> <item name="cardStyle">@style/CardView.Dark</item> ... </style> </resources> 

Затем в другом xml, чтобы использовать новый атрибут, вы будете использовать его так

 style="?attr/cardStyle" 

Чтобы узнать больше о том, как реализовать решение David Park …

Поместите это в attrs.xml:

 <declare-styleable name = "cardStyle"> <attr name="cardStyle" format="reference" /> </declare-styleable> <style name="Light" parent="Theme.AppCompat.NoActionBar"> <item name="cardStyle">@style/CardView.Light</item> </style> <style name="Dark" parent="Theme.AppCompat.NoActionBar"> <item name="cardStyle">@style/CardView.Dark</item> </style> 

Затем добавьте cardStyle в свою тему в styles.xml:

 <style name="AppThemeLight" parent="AppTheme.Base"/> <style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar"> <item name="cardStyle">@style/CardView.Light</item> </style> <style name="AppThemeDark" parent="AppTheme.Base.Dark"/> <style name="AppTheme.Base.Dark" parent="Theme.AppCompat.NoActionBar"> <item name="cardStyle">@style/CardView.Dark</item> </style> 

Затем используйте attr, где у вас есть CardView:

 <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/header_card" android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardCornerRadius="2dp" card_view:cardElevation="2dp" style="?attr/cardStyle"> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:id="@+id/header_title" </android.support.v7.widget.CardView> 

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

Итак, у меня есть BaseActivity, от которого распространяются все мои действия. В нем я обрабатываю изменение цвета карты в дополнение к обработке темы. Смотри ниже:

BaseActivity.java :

 public class BaseActivity extends ActionBarActivity { private static final int DEFAULT_THEME_ID = R.style.AppTheme_Dark; @Override protected void onCreate(Bundle savedInstanceState) { int theme_id = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getInt("THEME_ID", DEFAULT_THEME_ID); setTheme(theme_id); int card_color; if (theme_id == DEFAULT_THEME_ID){ card_color = R.color.cv_dark; } else{ card_color = R.color.cv_light; } Constants.CARD_COLOR = card_color; super.onCreate(savedInstanceState); } } 

Это определенно не лучший способ сделать это, но пока кто-то еще не найдет лучший способ реализовать стиль, это все, о чем я могу думать.

Intereting Posts