在多主题应用程序中更改单个视图样式的最佳方法 [英] Best way to change individual views styles in a multi Theme app

查看:60
本文介绍了在多主题应用程序中更改单个视图样式的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ListView和一个BaseAdapter,可以有许多不同的inflated views.我正在实现用户可以从应用程序中选择的树主题.一切都很棒,直到我需要根据用户选择的主题更改ListView中的行TextView的外观.

I have a ListView with a BaseAdapter that can have many different inflated views. I'm implementing tree Themes that user can choose from within the app. Everything was great until I needed to change the appearance of a row TextView in the ListView depending on the Theme user has chosen.

我有一个解决方案,可以像这样进行即时测试:

I have a solution where I'm on the fly testing like this:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    int type = getItemViewType(position);
    ViewHolder viewHolder = null;
    if (convertView == null) {
        switch (type) {
        case TYPE_ACTIVE: // inflate active accounts
            if (theme == SettingsManager.InterfaceTheme.light)
                convertView = inflator.inflate(R.layout.a_login_roaster_light, null);
            else if (theme == SettingsManager.InterfaceTheme.dark)
                convertView = inflator.inflate(R.layout.a_login_roaster_dark, null);
            else
                convertView = inflator.inflate(R.layout.a_login_roaster_def, null);
            viewHolder = new ViewHolder();
            viewHolder.text1 = (TextView) convertView.findViewById(R.id.txt_row1);
            viewHolder.text2 = (TextView) convertView.findViewById(R.id.txt_row2); 

如您所见,我通过增加ny行布局来更改外观.这是可行的,但一切都可以,但是有更好的方法可以实现,因为布局是相同的,仅颜色或字体大小必须更改?我正在使用android-support-v7-appcompat.jar,并将我的Application Manifest中的Theme.AppCompat.Light主题作为默认主题.我使用这个出色的工具 Android操作栏样式生成器

As you see I change the appearance by inflate a ny row layout. This is working and everything but is there a better way to do this since the layout is same only color or font size must change? I'm using the android-support-v7-appcompat.jar and have the Theme.AppCompat.Light Theme in my Application Manifest as default Theme. I made some Themes with this wondeful tool, Android Action Bar Style Generator

这是使用 Android操作栏样式生成器创建的样式,我发布了其中一棵树样式,因为它们是相同的.这是位于res \ values中的简易"版本文件

Here is the Style created with Android Action Bar Style Generator, I post one of tree styles since they are the same. This is the "light" version file located in res\values

<?xml version="1.0" encoding="utf-8"?>
<!-- File created by the Android Action Bar Style Generator

     Copyright (C) 2011 The Android Open Source Project
     Copyright (C) 2012 readyState Software Ltd

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<resources>

    <style name="Theme.theapp_light" parent="@style/Theme.AppCompat.Light">
        <item name="actionBarItemBackground">@drawable/selectable_background_theapp_light</item>
        <item name="popupMenuStyle">@style/PopupMenu.theapp_light</item>
        <item name="dropDownListViewStyle">@style/DropDownListView.theapp_light</item>
        <item name="actionBarTabStyle">@style/ActionBarTabStyle.theapp_light</item>
        <item name="actionDropDownStyle">@style/DropDownNav.theapp_light</item>
        <item name="actionBarStyle">@style/ActionBar.Solid.theapp_light</item>
        <item name="actionModeBackground">@drawable/cab_background_top_theapp_light</item>
        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_theapp_light</item>
        <item name="actionModeCloseButtonStyle">@style/ActionButton.CloseMode.theapp_light</item>


    </style>

    <style name="ActionBar.Solid.theapp_light" parent="@style/Widget.AppCompat.Light.ActionBar.Solid">
        <item name="background">@drawable/ab_solid_theapp_light</item>
        <item name="backgroundStacked">@drawable/ab_stacked_solid_theapp_light</item>
        <item name="backgroundSplit">@drawable/ab_bottom_solid_theapp_light</item>
        <item name="progressBarStyle">@style/ProgressBar.theapp_light</item>
    </style>

    <style name="ActionBar.Transparent.theapp_light" parent="@style/Widget.AppCompat.Light.ActionBar">
        <item name="background">@drawable/ab_transparent_theapp_light</item>
        <item name="progressBarStyle">@style/ProgressBar.theapp_light</item>
    </style>

    <style name="PopupMenu.theapp_light" parent="@style/Widget.AppCompat.Light.PopupMenu">  
        <item name="android:popupBackground">@drawable/menu_dropdown_panel_theapp_light</item>  
    </style>

    <style name="DropDownListView.theapp_light" parent="@style/Widget.AppCompat.Light.ListView.DropDown">
        <item name="android:listSelector">@drawable/selectable_background_theapp_light</item>
    </style>

    <style name="ActionBarTabStyle.theapp_light" parent="@style/Widget.AppCompat.Light.ActionBar.TabView">
        <item name="android:background">@drawable/tab_indicator_ab_theapp_light</item>
    </style>

    <style name="DropDownNav.theapp_light" parent="@style/Widget.AppCompat.Light.Spinner.DropDown.ActionBar">
        <item name="android:background">@drawable/spinner_background_ab_theapp_light</item>
        <item name="android:popupBackground">@drawable/menu_dropdown_panel_theapp_light</item>
        <item name="android:dropDownSelector">@drawable/selectable_background_theapp_light</item>
    </style>

    <style name="ProgressBar.theapp_light" parent="@style/Widget.AppCompat.ProgressBar.Horizontal">
        <item name="android:progressDrawable">@drawable/progress_horizontal_theapp_light</item>
    </style>

    <style name="ActionButton.CloseMode.theapp_light" parent="@style/Widget.AppCompat.Light.ActionButton.CloseMode">
        <item name="android:background">@drawable/btn_cab_done_theapp_light</item>
    </style>

    <!-- this style is only referenced in a Light.DarkActionBar based theme -->
    <style name="Theme.theapp_light.Widget" parent="@style/Theme.AppCompat">
        <item name="popupMenuStyle">@style/PopupMenu.theapp_light</item>
        <item name="dropDownListViewStyle">@style/DropDownListView.theapp_light</item>
    </style>

</resources>

这是位于res \ values中的颜色资源样式

And this is color resources style located in res\values

<resources>
    <color name="pressed_theapp_light">#CCFC4C5D</color>
</resources>

推荐答案

编辑:我更新了以下所有内容,以包括定义为在列表上设置自动样式的样式multiListItem项目.

EDIT: I updated all the content below to include the style multiListItem that I defined to setup an automated style on the list items.

这是我在应用程序上使用的让用户在主题之间切换的方式:

Here is the way I use on my app to let the user switch between themes:

首先,我准备文件styles.xml中的不同主题,这是一个简单的示例,其中我修改了系统上的默认基本颜色:

First I prepare the different themes in the file styles.xml, here is an easy example where I modify the default basic colors on the system:

<!-- *** DEFAULT THEME *** -->
    <style name="AppTheme" parent="@android:style/Theme.Holo.Light">
        <item name="android:textColorPrimary">?mainColor</item>
        <item name="android:textColorSecondary">?darkColor</item>
        <item name="android:textColorTertiary">?lightColor</item>
    </style>

    <!-- *** ORANGE THEME *** -->
    <style name="AppThemeOrange" parent="@style/AppTheme">
        <item name="mainColor">@color/orange_main</item>
        <item name="lightColor">@color/orange_light</item>
        <item name="darkColor">@color/orange_dark</item>

        <item name="multiListItem">@style/OrangeListViewItemStyle</item>
    </style>

    <!-- *** PURPLE THEME *** -->
    <style name="AppThemePurple" parent="@style/AppTheme">
        <item name="mainColor">@color/purple_main</item>
        <item name="lightColor">@color/purple_light</item>
        <item name="darkColor">@color/purple_dark</item>

        <item name="multiListItem">@style/PurpleListViewItemStyle</item>
    </style>

我还添加了两个主题所需的两种样式:

I also add the 2 styles needed for the 2 themes:

<style name="OrangeListViewItemStyle">
        <item name="android:textColor">@color/OrangeMain</item>
        <item name="android:textSize">18sp</item>
    </style>

<style name="PurpleListViewItemStyle">
        <item name="android:textColor">@color/PurpleMain</item>
        <item name="android:textSize">20sp</item>
    </style>

然后在列表行项目上调用样式multiListItem,在这种情况下,我在此布局中使用了该样式(对于列表中的每一行,该布局都被夸大了):

The style multiListItem is then called on the list row items, for this case I used it in this layout (the layout inflated for each row in my list):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/filter_list_child_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:orientation="horizontal" >

    <CheckBox
        android:id="@+id/filter_list_child_checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:longClickable="false" />

    <TextView
        android:id="@+id/filter_list_child_textview"
        style="?multiListItem"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>

因此,我有一个默认主题,该主题实际上是从特定的Orange和Purple主题加载引用. 为此,我在文件values\attrs.xml中添加了引用:

So I have a default theme that is actually loading references from the specific Orange and Purple themes. In order to do this I added the references in the file values\attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
  <resources>
       <attr name="mainColor" format="reference"/>
       <attr name="lightColor" format="reference"/>
       <attr name="darkColor" format="reference"/>

       <attr name="multiListItem" format="reference" />
  </resources>

我还用文件夹color中的样式创建了我调用的所有selectors,例如orange_dark.xml:

I also created all the selectors I call in the styles in the folder color, here is orange_dark.xml for example:

<?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/TextGray"/>
    <item android:state_pressed="true" android:color="@color/OrangeLightBackground"/>
    <item android:color="@color/OrangeDark"/>
</selector>

所有这些准备就绪后,我将使用共享的首选项加载正确的主题.通过填充以下内容的列表首选项,主题可以作为常规设置使用:

Once all this is prepared, I load the right theme using the shared preferences. The theme is just available as a normal setting through a list preference populated with this:

<string-array name="themes_strings">
        <item>Purple</item>
        <item>Orange</item>
    </string-array>
    <string-array name="themes_values">
        <item>purple</item>
        <item>orange</item>
    </string-array>

然后要检索在设置中选择的主题,我只使用以下简单功能:

Then to retrieve the theme selected in the settings, I just use this simple function:

public int getThemeID() {

        String themeSelected = _sharedPrefs.getString(PREF_KEY_THEME, DEFAULT_THEME);
        if(themeSelected.equalsIgnoreCase("orange")){
            return THEME_ORANGE_ID;
        }
        else if(themeSelected.equalsIgnoreCase("purple")){
            return THEME_PURPLE_ID;
        }
        else{
            return THEME_PURPLE_ID;
        }
    }

常量是直接使用主题引用定义的:

The constants are defined using the themes references directly:

public static final int THEME_ORANGE_ID = R.style.AppThemeOrange;
public static final int THEME_PURPLE_ID = R.style.AppThemePurple;

然后使用以下行将所选主题应用于活动:

Then the theme selected is applied on the activities using this line:

setTheme(mPrefs.getThemeID());

mPrefs只是一个帮助器类,收集我所有共享的首选项获取器和设置器.

mPrefs is just a helper class gathering all my shared preferences getters and setters.

希望它会给您一些想法!

Hope it will give you some ideas!

这篇关于在多主题应用程序中更改单个视图样式的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆