【问题标题】:How to give the user the possibility to switch between different colors skin in your App如何让用户可以在您的应用程序中切换不同颜色的皮肤
【发布时间】:2016-11-15 21:27:42
【问题描述】:

我想让用户有机会选择应用程序的颜色皮肤。例如,我应该实现具有不同色调的黑色的黑色皮肤和具有不同色调的白色皮肤。

实现这一目标的最佳方法是什么?

例如,我知道 Android 中有一个 colors.xml 文件,其中应该包含您应用的颜色。谁是一种拥有两种颜色文件或其他东西并根据用户选择使用一种或其他的方法?也许是一个styles.xml 文件?

请告诉我您对实现这一目标的最佳方法的看法

谢谢

我的布局:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content view -->
    <RelativeLayout
        android:id="@+id/main_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v4.view.ViewPager
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v4.view.PagerTitleStrip
                android:id="@+id/pager_title_strip"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="top"
                android:paddingTop="4dp"
                android:paddingBottom="4dp"
                style="@style/CustomPagerTitleStrip"/>
        </android.support.v4.view.ViewPager>
    </RelativeLayout>
    <!-- The navigation drawer -->
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer_menu"
        style="@style/NavigationDrawerStyle"/>
</android.support.v4.widget.DrawerLayout>

我的styles.xml 文件:

<resources>
    <style name="AppTheme" parent="Theme.AppCompat">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="actionBarTheme">@style/CustomActionBar</item>
        <item name="android:textColor">@color/colorFontMenus</item>
        <item name="itemTextColor">@color/colorFontMenus</item>
        <item name="itemIconTint">@color/colorFontMenus</item>
    </style>

    <style name="CustomActionBar">
        <!-- title text color -->
        <item name="android:textColorPrimary">@color/colorFontMenus</item>
        <!-- subtitle text color -->
        <item name="android:textColorSecondary">?android:textColorPrimary</item>
        <!-- action menu item text color -->
        <item name="actionMenuTextColor">?android:textColorPrimary</item>
        <!-- action menu item icon color - only applies to appcompat-v7 icons :( -->
        <item name="colorControlNormal">?android:textColorPrimary</item>
    </style>

    <style name="CustomPagerTitleStrip">
        <item name="android:background">@color/mainColorWithAlpha</item>
    </style>

    <style name="CustomTextView">
        <item name="android:textColor">@color/colorFontContent</item>
    </style>

    <style name="CustomScrollBar">
        <item name="android:scrollbarThumbVertical">@drawable/scrollbar_green</item>
    </style>

    <style name="CustomDrawerHeader">
        <item name="android:background">@drawable/drawer_header_background_green</item>
    </style>

    <style name="NavigationDrawerStyle">
        <item name="android:background">@color/colorPrimaryDark</item>
   </style>

</resources>

【问题讨论】:

  • 我没有发布正确答案的所有详细信息,只是为了提供指导:将其与样式/主题一起使用。在这里你可以找到如何在运行时在它们之间进行更改stackoverflow.com/questions/19125163/…
  • @NullPointerException 实际上我正在我的应用程序中执行此操作,但我不会更改整个主题。我只是根据SharedPreferences 中的颜色值以编程方式更改Statusbar 颜色、Toolbar 颜色、Fab 颜色和任何其他我想要的颜色。如果你愿意,我可以给你我的代码。但是如果你想检查一下我可以建议你看看这个:android-change-app-theme-runtime
  • @NullPointerException 我已经写了一个关于如何得到这个的解释,还发布了一些资源,这样你就可以对这个问题有更广泛的了解。

标签: android android-styles android-color


【解决方案1】:

关于@Joaquim Ley 的回答,我们可以在super.onCreate() 之前更改主题。

在我的应用程序中(工作中)我的styles.xml

这是我的默认主题

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="android:colorAccent">@color/colorPrimary</item>
    <item name="android:statusBarColor">@color/colorPrimaryDark</item>
    <item name="android:colorFocusedHighlight">@color/colorPrimary</item>
    <item name="android:colorControlNormal">@color/amber_300</item>
    <item name="android:colorControlActivated">@color/amber_300</item>
    <item name="android:colorControlHighlight">@color/colorControlHighlight</item>
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
    <item name="android:windowTranslucentStatus">false</item>
    <item name="actionBarItemBackground">?attr/selectableItemBackground</item>
    <item name="colorControlHighlight">@color/colorControlHighlight</item>
    <item name="android:windowContentTransitions">true</item>
    <!-- Customize your theme here. -->
</style>

这是我的绿色主题:

<style name="AppTheme.Green" parent="AppTheme">
    <item name="colorPrimary">@color/green_500</item>
    <item name="colorPrimaryDark">@color/green_700</item>
    <item name="android:colorAccent">@color/green_300</item>
    <item name="android:statusBarColor">@color/green_700</item>
    <item name="android:colorFocusedHighlight">@color/green_500</item>
    <item name="android:colorControlNormal">@color/green_300</item>
    <item name="android:colorControlActivated">@color/green_300</item>
</style>

更换主题时:

@Override
protected void onCreate(Bundle savedInstanceState) {
    mPrefs=getSharedPreferences(getResources().getString(R.string.preference_name),MODE_PRIVATE);
    mEditor=mPrefs.edit();
    mEditor.apply();
    defaultColor=mPrefs.getInt(getResources().getString(R.string.default_color),0);
    //you can do some switch case or if else of defaultColor and change theme
    setTheme(R.style.AppTheme_Green);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_voice_record);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
}

这是我的第一个工作应用程序,但在我的个人应用程序中,我创建了一个 BaseActivity 并创建了一个方法 handleColor(int color,int darkcolor)。但这不会改变整个主题,只是 ToolbarStatusBarNavigationBarEditText 标记和下划线颜色:

public class BaseActivity extends AppCompatActivity {

public void handleColor(int color,int darkcolor){
    //changing toolbar color
    if(getSupportActionBar()!=null){
        getSupportActionBar().setBackgroundDrawable(new ColorDrawable(color));
    }

    //if bigger than Api 21 change status bar color
    if(isLolipop()){
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(darkcolor);
    }
}

public boolean isLolipop(){
    return  Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
  }

}

更改颜色时,我使用的是材质对话框颜色选择器。示例 apk:sample.apkGithubmaterial-dialogs。如果你想看看它的样子,我可以给你一个我的应用程序的视频。

颜色来自:Material Color Palette

无论如何我知道两种不同的方法,如果你喜欢其中一种,我可以解释更多。

@Edit : 好消息,我找到了这个 Github 存储库:app-theme-engine,它运行良好。您可以尝试示例 apk。如果你不能通过 gradle 导入它,试试这个:compile 'com.github.naman14:app-theme-engine:0.5.1@aar'

【讨论】:

  • 嗨。谢谢你。可以使用 colors.xml 文件切换使用的颜色吗?它应该比这两种方法更有效。例如,使用两个colors.xml 文件,或colors.xml 文件中的两组颜色,两组中每种颜色的名称都相同。这可能吗?
  • @NullPointerException 对于您的第一个问题:我从未见过/听说过任何使用许多colors.xml 的开发人员,对于您的第二个问题:您只能使用一次颜色名称。但是您可以阅读此页面:UiModeManager 并尝试实现夜间模式。
  • 再想一想,“AppTheme”自定义样式中的某些项目不能更改,必须在其他自定义样式中更改,例如CustomActionBar,CustomPagerTitleStrip,CustomScrollBar...等您如何应用这些自定义样式?
  • @NullPointerException 你能给我一些代码吗,我可以在运行时(以编程方式)更改 ScrollView 的滚动条颜色。但我从未尝试过CustomActionBar、CustomPagerTitleStrip。如果你明确了你想做什么,那么我会很容易地帮助你。
  • Yasin Kaçmaz 当然,我编辑了我的问题,添加了我的布局。如您所见,我正在为我的视图组件使用自定义样式。
【解决方案2】:

这应该在样式/AppTheme.xml 中完成

只能在 onCreate() 方法中更改 Activity 的主题,并且只能在调用 super() 之前更改。更改主题相当简单,如下所示:

setTheme(someBooleanFlag ? R.style.AppThemeOne : R.style.AppThemeTwo);

在此处阅读更多信息:

Ali Muzaffar's Medium post on this

Styles and Themes

Material Theme

【讨论】:

  • Joaquim Ley 某些项目在“AppTheme”自定义样式中无法更改,必须在其他自定义样式中更改,例如 CustomActionBar、CustomPagerTitleStri‌​p、CustomScrollBar... 等。如何切换到其他自定义样式这些自定义样式的肤色?我编辑了我的问题,添加了我的 styles.xml 文件和我的布局文件。
  • 您可以使用 OtherCustomStyle parent="AppTheme" 指定新样式
猜你喜欢
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 2021-08-29
  • 1970-01-01
相关资源
最近更新 更多