4

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

我有一个解决方案,我正在像这样进行动态测试:

@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); 

如您所见,我通过增加任何行布局来更改外观。这是可行的,但有没有更好的方法来做到这一点,因为布局相同,只有颜色或字体大小必须改变?我正在使用 android-support-v7-appcompat.jar 并将我的应用程序清单中的 Theme.AppCompat.Light 主题作为默认主题。我用这个很棒的工具制作了一些主题,Android Action Bar Style Generator

这是使用Android 操作栏样式生成器创建的样式,我发布了一种树样式,因为它们是相同的。这是位于 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 中的颜色资源样式

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

1 回答 1

2

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

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

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

<!-- *** 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>

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

<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,对于这种情况,我在此布局中使用它(布局为列表中的每一行膨胀):

<?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>

所以我有一个默认主题,它实际上是从特定的橙色和紫色主题加载引用。为了做到这一点,我在文件中添加了引用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>

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

<?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>

准备好所有这些后,我使用共享首选项加载正确的主题。该主题仅可作为正常设置通过使用以下内容填充的列表首选项提供:

<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>

然后检索设置中选择的主题,我只使用这个简单的功能:

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;
        }
    }

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

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

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

setTheme(mPrefs.getThemeID());

mPrefs只是一个帮助类,收集我所有的共享偏好获取器和设置器。

希望能给大家一些思路!

于 2013-10-01T04:02:08.807 回答