问题
I want to give the user the opportunity to select wich color skin will have the app. For example, i whould implement a black skin with black colours with different tonalities and also a white skin with withe tonalities.
Which whould be the best approach to achieve this?
For example i know that there is a colors.xml file in Android that should contain the colours of your app. Whould be a way to have two colors files or something and to use one or other depending of user selection? Maybe a styles.xml file?
Please tell me your opinion about which whould be the best approach to achieve this
Thank you
MY LAYOUT:
<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>
My styles.xml file:
<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>
回答1:
Regarding to @Joaquim Ley's answer we can change Theme before super.onCreate()
.
In my app(at work) my styles.xml
:
This is my default theme
<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>
And this is my Green Theme :
<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>
When changing theme :
@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);
}
This is my first app in work, but in my personal app i created a BaseActivity
and created a method handleColor(int color,int darkcolor)
. But this won't change entire theme just Toolbar
, StatusBar
, NavigationBar
and EditText
marker and underline colors:
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;
}
}
When changing color i am using Material Dialogs Color Picker. Sample apk : sample.apk and Github
: material-dialogs. If you want to see how it looks like i can give you a video of my app.
Colors from : Material Color Palette
Anyways i know 2 different approach , if you like one of them i can explain more.
@Edit :
Good news for you, I found this Github repo : app-theme-engine and its working good. You can try sample apk. If you can't import it via gradle try this : compile 'com.github.naman14:app-theme-engine:0.5.1@aar'
回答2:
This should be done in the styles/AppTheme.xml
It’s only possible to change the theme of an Activity in the onCreate()
method and that to only before super()
has been called. Changing the theme is fairly straight forward, something like below should do it:
setTheme(someBooleanFlag ? R.style.AppThemeOne : R.style.AppThemeTwo);
Read more here:
Ali Muzaffar's Medium post on this
Styles and Themes
Material Theme
来源:https://stackoverflow.com/questions/38349187/how-to-give-the-user-the-possibility-to-switch-between-different-colors-skin-in