利用ToolBar实现主题切换原理:切换主题时,将颜色值存储到Preference中,同时更新主题样式。再次打开App读取Preference对应的颜色值,设置主题样式即可。
- 主要使用方法如下:
1)设置ToolBar的背景颜色:toolbar.setBackgroundColor()。
2)设置窗体状态栏透明:getWindow().setStatusBarColor()。
3)设置窗体导航栏底色:getWindow().setNavigationBarColor();
首先看一下效果图:
converted_file_44df3f12.gif1. 创建一个Activity ,设置主题为"@style/Theme.AppCompat.Light.NoActionBar"。
<activity android:name=".MainActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
2. 在style.xml中自定义主题样式。
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/accent_amber</item>
<item name="colorPrimaryDark">@color/accent_amber</item>
<item name="colorAccent">@color/accent_amber</item>
</style>
<style name="MyToolbar" parent="Widget.AppCompat.Toolbar">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:elevation" tools:ignore="NewApi">5dp</item>
<item name="theme">@style/MyToolbarTheme</item>
</style>
<style name="MyToolbarTheme" parent="ThemeOverlay.AppCompat.ActionBar">
<item name="android:textColorPrimary">#FFF</item>
<item name="colorControlNormal">#FFF</item>
<item name="colorControlHighlight">#FFF</item>
</style>
</resources>
3. 自定义toolbar.xml,使用自定义的主题MyToolBar。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/MyToolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>
4. 在Activity布局中使用toolbar.xml。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</LinearLayout>
5. 设置主题基础ThemeActivity,负责设置更改主题。
package cn.studyou.themedeep.base;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SwitchCompat;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.ScrollView;
import android.widget.SeekBar;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.context.IconicsContextWrapper;
import com.mikepenz.iconics.typeface.IIcon;
import java.util.ArrayList;
import cn.studyou.themedeep.R;
import cn.studyou.themedeep.utils.ColorPaletteUtils;
import cn.studyou.themedeep.utils.PreferenceUtils;
import cn.studyou.themedeep.utils.ThemeUtils;
/**
* 基本功能:主题
* 创建:王杰
* 创建时间:2017/2/27
* 邮箱:w489657152@gmail.com
*/
public class ThemeActivity extends AppCompatActivity {
private ThemeUtils themeUtils;
private PreferenceUtils SP;
private boolean coloredNavBar;
private boolean obscuredStatusBar;
private boolean applyThemeImgAct;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SP = PreferenceUtils.getInstance(getApplicationContext());
themeUtils = new ThemeUtils(getApplicationContext());
}
@Override
public void onResume() {
super.onResume();
updateTheme();
}
public void updateTheme() {
themeUtils.updateTheme();
coloredNavBar = SP.getBoolean(getString(R.string.preference_colored_nav_bar), false);
obscuredStatusBar = SP.getBoolean(getString(R.string.preference_translucent_status_bar), true);
applyThemeImgAct = SP.getBoolean(getString(R.string.preference_apply_theme_pager), true);
}
@Override
protected void attachBaseContext(Context newBase) {
// NOTE: icons stuff
super.attachBaseContext(IconicsContextWrapper.wrap(newBase));
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void setNavBarColor() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (isNavigationBarColored()) getWindow().setNavigationBarColor(getPrimaryColor());
else
getWindow().setNavigationBarColor(ContextCompat.getColor(getApplicationContext(), R.color.md_black_1000));
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
protected void setStatusBarColor() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (isTranslucentStatusBar())
getWindow().setStatusBarColor(ColorPaletteUtils.getObscuredColor(getPrimaryColor()));
else
getWindow().setStatusBarColor(getPrimaryColor());
}
}
protected void setScrollViewColor(ScrollView scr) {
themeUtils.setScrollViewColor(scr);
}
public void setCursorDrawableColor(EditText editText, int color) {
// TODO: 02/08/16 remove this
ThemeUtils.setCursorDrawableColor(editText, color);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void setRecentApp(String text) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
BitmapDrawable drawable = ((BitmapDrawable) getDrawable(R.mipmap.ic_launcher));
setTaskDescription(new ActivityManager.TaskDescription(text, drawable.getBitmap(), getPrimaryColor()));
}
}
public boolean isNavigationBarColored() {
return coloredNavBar;
}
public boolean isTranslucentStatusBar() {
return obscuredStatusBar;
}
protected boolean isApplyThemeOnImgAct() {
return applyThemeImgAct;
}
protected boolean isTransparencyZero() {
return 255 - SP.getInt(getString(R.string.preference_transparency), 0) == 255;
}
public int getTransparency() {
return 255 - SP.getInt(getString(R.string.preference_transparency), 0);
}
public void setBaseTheme(int baseTheme, boolean permanent) {
themeUtils.setBaseTheme(baseTheme, permanent);
}
public void themeSeekBar(SeekBar bar) {
themeUtils.themeSeekBar(bar);
}
public int getPrimaryColor() {
return themeUtils.getPrimaryColor();
}
public int getAccentColor() {
return themeUtils.getAccentColor();
}
public int getBaseTheme() {
return themeUtils.getBaseTheme();
}
protected int getBackgroundColor() {
return themeUtils.getBackgroundColor();
}
protected Drawable getPlaceHolder() {
return themeUtils.getPlaceHolder();
}
protected int getInvertedBackgroundColor() {
return themeUtils.getInvertedBackgroundColor();
}
public int getTextColor() {
return themeUtils.getTextColor();
}
public int getSubTextColor() {
return themeUtils.getSubTextColor();
}
public int getCardBackgroundColor() {
return themeUtils.getCardBackgroundColor();
}
public int getIconColor() {
return themeUtils.getIconColor();
}
protected int getDrawerBackground() {
return themeUtils.getDrawerBackground();
}
public int getDialogStyle() {
return themeUtils.getDialogStyle();
}
protected int getPopupToolbarStyle() {
return themeUtils.getPopupToolbarStyle();
}
protected ArrayAdapter<String> getSpinnerAdapter(ArrayList<String> items) {
return themeUtils.getSpinnerAdapter(items);
}
protected int getDefaultThemeToolbarColor3th() {
return themeUtils.getDefaultThemeToolbarColor3th();
}
protected void updateRadioButtonColor(RadioButton radioButton) {
themeUtils.updateRadioButtonColor(radioButton);
}
protected void setRadioTextButtonColor(RadioButton radioButton, int color) {
themeUtils.setRadioTextButtonColor(radioButton, color);
}
public void updateSwitchColor(SwitchCompat sw, int color) {
themeUtils.updateSwitchColor(sw, color);
}
public IconicsDrawable getToolbarIcon(IIcon icon) {
return themeUtils.getToolbarIcon(icon);
}
}
6. 所有Activity继承ThemeActivity设置主题。
package cn.studyou.themedeep.ui;
import android.content.DialogInterface;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.CardView;
import android.support.v7.widget.SwitchCompat;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import cn.studyou.themedeep.R;
import cn.studyou.themedeep.base.ThemeActivity;
import cn.studyou.themedeep.utils.ColorPaletteUtils;
import cn.studyou.themedeep.utils.PreferenceUtils;
import uz.shift.colorpicker.LineColorPicker;
import uz.shift.colorpicker.OnColorChangedListener;
public class SettingActivity extends ThemeActivity {
private SwitchCompat swNavBar;
private LinearLayout swNavBarStatus;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
initView();
}
private Toolbar toolbar;
private PreferenceUtils SP;
private Button changeThemeButton;
private TextView toolbarTitle;
private SwitchCompat setTranslucentStatusBar;
private LinearLayout translucentStatusBarStatus;
private void initView() {
SP = PreferenceUtils.getInstance(getApplicationContext());
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbarTitle = (TextView) findViewById(R.id.toolbar_title);
setSupportActionBar(toolbar);
changeThemeButton = (Button) findViewById(R.id.changeTheme);
setTranslucentStatusBar = (SwitchCompat) findViewById(R.id.set_translucent_status_bar);
translucentStatusBarStatus = (LinearLayout) findViewById(R.id.translucent_status_bar_status);
swNavBar = (SwitchCompat) findViewById(R.id.set_colored_navBar);
swNavBarStatus = (LinearLayout) findViewById(R.id.set_colored_navBar_status);
changeThemeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
primaryColorPiker();
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
translucentStatusBarStatus.setVisibility(View.VISIBLE);
swNavBarStatus.setVisibility(View.VISIBLE);
}
setTranslucentStatusBar.setChecked(SP.getBoolean(getString(R.string.preference_translucent_status_bar), true));
setTranslucentStatusBar.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SP.putBoolean(getString(R.string.preference_translucent_status_bar), isChecked);
updateTheme();
setStatusBarColor();
updateSwitchColor(setTranslucentStatusBar, getAccentColor());
}
});
toolbarTitle.setText(R.string.setting);
toolbar.setNavigationIcon(getToolbarIcon(GoogleMaterial.Icon.gmd_arrow_back));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
swNavBar.setChecked(SP.getBoolean(getString(R.string.preference_colored_nav_bar), false));
swNavBar.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SP.putBoolean(getString(R.string.preference_colored_nav_bar), isChecked);
updateTheme();
updateSwitchColor(swNavBar, getAccentColor());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setNavigationBarColor(isNavigationBarColored() ? getPrimaryColor() : ContextCompat.getColor(getApplicationContext(), R.color.md_black_1000));
}
}
});
}
private void primaryColorPiker() {
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this, getDialogStyle());
final View dialogLayout = getLayoutInflater().inflate(R.layout.color_piker_primary, null);
final LineColorPicker colorPicker = (LineColorPicker) dialogLayout.findViewById(R.id.color_picker_primary);
final LineColorPicker colorPicker2 = (LineColorPicker) dialogLayout.findViewById(R.id.color_picker_primary_2);
final TextView dialogTitle = (TextView) dialogLayout.findViewById(R.id.cp_primary_title);
CardView dialogCardView = (CardView) dialogLayout.findViewById(R.id.cp_primary_card);
dialogCardView.setCardBackgroundColor(getCardBackgroundColor());
colorPicker.setColors(ColorPaletteUtils.getBaseColors(getApplicationContext()));
for (int i : colorPicker.getColors())
for (int i2 : ColorPaletteUtils.getColors(getBaseContext(), i))
if (i2 == getPrimaryColor()) {
colorPicker.setSelectedColor(i);
colorPicker2.setColors(ColorPaletteUtils.getColors(getBaseContext(), i));
colorPicker2.setSelectedColor(i2);
break;
}
dialogTitle.setBackgroundColor(getPrimaryColor());
colorPicker.setOnColorChangedListener(new OnColorChangedListener() {
@Override
public void onColorChanged(int c) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (isTranslucentStatusBar()) {
getWindow().setStatusBarColor(ColorPaletteUtils.getObscuredColor(getPrimaryColor()));
} else getWindow().setStatusBarColor(c);
}
toolbar.setBackgroundColor(c);
dialogTitle.setBackgroundColor(c);
colorPicker2.setColors(ColorPaletteUtils.getColors(getApplicationContext(), colorPicker.getColor()));
colorPicker2.setSelectedColor(colorPicker.getColor());
}
});
colorPicker2.setOnColorChangedListener(new OnColorChangedListener() {
@Override
public void onColorChanged(int c) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (isTranslucentStatusBar()) {
getWindow().setStatusBarColor(ColorPaletteUtils.getObscuredColor(c));
} else getWindow().setStatusBarColor(c);
if (isNavigationBarColored())
getWindow().setNavigationBarColor(c);
else
getWindow().setNavigationBarColor(ContextCompat.getColor(getApplicationContext(), R.color.md_black_1000));
}
toolbar.setBackgroundColor(c);
dialogTitle.setBackgroundColor(c);
}
});
dialogBuilder.setView(dialogLayout);
dialogBuilder.setNeutralButton(getString(R.string.cancel).toUpperCase(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (isTranslucentStatusBar()) {
getWindow().setStatusBarColor(ColorPaletteUtils.getObscuredColor(getPrimaryColor()));
} else getWindow().setStatusBarColor(getPrimaryColor());
}
toolbar.setBackgroundColor(getPrimaryColor());
dialog.cancel();
}
});
dialogBuilder.setPositiveButton(getString(R.string.ok_action).toUpperCase(), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SP.putInt(getString(R.string.preference_primary_color), colorPicker2.getColor());
updateTheme();
setNavBarColor();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (isTranslucentStatusBar()) {
getWindow().setStatusBarColor(ColorPaletteUtils.getObscuredColor(getPrimaryColor()));
} else {
getWindow().setStatusBarColor(getPrimaryColor());
}
}
}
});
dialogBuilder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (isTranslucentStatusBar()) {
getWindow().setStatusBarColor(ColorPaletteUtils.getObscuredColor(getPrimaryColor()));
} else getWindow().setStatusBarColor(getPrimaryColor());
if (isNavigationBarColored())
getWindow().setNavigationBarColor(getPrimaryColor());
else
getWindow().setNavigationBarColor(ContextCompat.getColor(getApplicationContext(), R.color.md_black_1000));
}
toolbar.setBackgroundColor(getPrimaryColor());
}
});
dialogBuilder.show();
}
@Override
public void onResume() {
super.onResume();
updateNowTheme();
}
private void updateNowTheme() {
toolbar.setPopupTheme(getPopupToolbarStyle());
toolbar.setBackgroundColor(getPrimaryColor());
toolbar.setTitle("");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (isTranslucentStatusBar()) {
getWindow().setStatusBarColor(ColorPaletteUtils.getObscuredColor(getPrimaryColor()));
} else {
getWindow().setStatusBarColor(getPrimaryColor());
}
getWindow().setNavigationBarColor(isNavigationBarColored() ? getPrimaryColor() : ContextCompat.getColor(getApplicationContext(), R.color.md_black_1000));
}
}
}
7. 选取主题颜色写到color.xml中供后续使用(更多颜色值见源码)。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--Accent Color Collection-->
<color name="accent_red">#f44336</color>
<color name="accent_pink">#e91e63</color>
<color name="accent_purple">#9c27b0</color>
<color name="accent_deep_purple">#673ab7</color>
<color name="accent_indago">#3f51b5</color>
<color name="accent_blue">#2196f3</color>
<color name="accent_cyan">#00bcd4</color>
<color name="accent_teal">#009688</color>
<color name="accent_green">#4caf50</color>
<color name="accent_yellow">#ffeb3b</color>
<color name="accent_amber">#ffc107</color>
<color name="accent_orange">#ff9800</color>
<color name="accent_brown">#795548</color>
<color name="accent_white">#FFFFFF</color>
<color name="accent_grey">#9e9e9e</color>
<color name="accent_black">#000000</color>
</resources>
总结:
网友评论