Android 实现一键切换应用主题颜色

最近项目中要实现切换应用主题的功能,下面就来说一说我在项目中是怎么实现这个功能的,一般我们需要改变整个应用的背景颜色可以直接这样设置getWindow().getDecorView().setBackgroundColor(int
color)
。但是这种方式显然不是我们想要的,而且还有许多不好的地方。为什么呢?第一、它会把整个页面的背景颜色都改变了。第二、布局的背景还必须是透明的才会有效果。所以这种方式有的时候是满足不了我们的需求的。下面我将为大家介绍我的解决方案,下面是一个实现的效果图。

上面效果图中点击设置应用主题颜色按钮,然后跳转至主题颜色选择界面,在界面中选择相应的主题颜色,可以发现界面的title布局会立即跟随所选择的主题颜色进行切换。下面我将贴出相应的代码片段。

1、定义一个监听颜色改变的接口

public interface OnColorChangedListener {
	void onColorChanged(int color);
}

2、创建一个主题颜色管理类

import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import com.qiulong.changedmotivecolortest.R;
import com.qiulong.changedmotivecolortest.activity.MyApplication;

public class ColorManager {

	public static final int DEFAULT_COLOR = 0xFF0C89D8;
	private final List<OnColorChangedListener> listeners = new ArrayList<OnColorChangedListener>();
	private int mCurrentColor = DEFAULT_COLOR;
	private static ColorManager instance;

	public static ColorManager getInstance() {
		if (instance == null) {
			return instance = new ColorManager();
		}
		return instance;
	}

	public void addListener(OnColorChangedListener listener) {
		if (!this.listeners.contains(listener)) {
			if (listener != null) {
				listener.onColorChanged(mCurrentColor);
				this.listeners.add(listener);
			}
		}
	}

	public void removeListener(OnColorChangedListener listener) {
		this.listeners.remove(listener);
	}

	public void notifyColorChanged(int color) {
		if (mCurrentColor == color) {
			return;
		}
		mCurrentColor = color;
		for (OnColorChangedListener listener : this.listeners) {
			if (listener != null) {
				listener.onColorChanged(color);
			}
		}
	}

	public int[] getSkinColor(Context context) {
		return context.getResources().getIntArray(R.array.default_color_array);
	}

	public void setSkinColor(Context context, int position) {
		int[] colorArr = context.getResources().getIntArray(
				R.array.default_color_array);
		MyApplication.mPreference.setSkinColorValue(colorArr[position]);
		notifyColorChanged(colorArr[position]);
	}

}

3、自定义一个LinearLayout重写onAttachedToWindow以及onDetachedFromWindow方法,以及实现OnColorChangedListener监听接口的OnColorChanged(int color)方法,当然你也可以继承其它的View。

import com.qiulong.changedmotivecolortest.mode.ColorManager;
import com.qiulong.changedmotivecolortest.mode.OnColorChangedListener;
import android.content.Context;
import android.graphics.LightingColorFilter;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.widget.LinearLayout;

public class ColorLinearLayout extends LinearLayout implements
		OnColorChangedListener {

	public ColorLinearLayout(Context context, AttributeSet attrs,
			int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
	}

	public ColorLinearLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public ColorLinearLayout(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onColorChanged(int color) {
		if (getBackground() != null
				&& !(getBackground() instanceof ColorDrawable)) {
			getBackground().setColorFilter(new LightingColorFilter(color, 1));
		} else {
			setBackgroundColor(color);
		}
	}

	@Override
	protected void onAttachedToWindow() {
		ColorManager.getInstance().addListener(this);
		super.onAttachedToWindow();
	}

	@Override
	protected void onDetachedFromWindow() {
		ColorManager.getInstance().removeListener(this);
		super.onDetachedFromWindow();
	}

}

4、主题颜色选择Activity

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import com.qiulong.changedmotivecolortest.R;
import com.qiulong.changedmotivecolortest.mode.ColorManager;

public class MotiveActivity extends Activity {

	private final int[] layouts = { R.id.skin_01, R.id.skin_02, R.id.skin_03,
			R.id.skin_04, R.id.skin_05 };

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_motive);
		initView();
	}

	private void initView() {
		findViewById(R.id.motive_back).setOnClickListener(
				new OnClickListener() {
					@Override
					public void onClick(View v) {
						finish();
					}
				});
		int colorArr[] = ColorManager.getInstance().getSkinColor(this);
		for (int i = 0; i < layouts.length; i++) {
			View view = findViewById(layouts[i]);
			View color = view.findViewById(R.id.motive_item_color);
			View selected = view.findViewById(R.id.motive_item_selected);
			color.setBackgroundColor(colorArr[i]);
			if (colorArr[i] == MyApplication.mPreference.getSkinColorValue()) {
				selected.setVisibility(View.VISIBLE);
			}
			color.setOnClickListener(new OnSkinColorClickListener(i));
		}
	}

	class OnSkinColorClickListener implements OnClickListener {

		private int position;

		public OnSkinColorClickListener(int position) {
			this.position = position;
		}

		@Override
		public void onClick(View v) {
			for (int i = 0; i < layouts.length; i++) {
				View view = findViewById(layouts[i]);
				View selected = view.findViewById(R.id.motive_item_selected);
				selected.setVisibility(i == position ? View.VISIBLE : View.GONE);
				ColorManager.getInstance().setSkinColor(MotiveActivity.this,
						position);
			}
		}
	}

}

5、最后贴上主题颜色集arrays.xml

<!-- 应用主题颜色 -->
    <integer-array name="default_color_array">
        <item>0xFF0C89D8</item>
        <item>0xFFB32CD1</item>
        <item>0xFFF676C1</item>
        <item>0xFF04BA19</item>
        <item>0xFF18D9BF</item>
    </integer-array>

由于时间的关系,现在只贴上相应的代码,以后再做详细的解释吧!其实都很简单的,不懂的朋友可以提问。以上内容仅供参考和学习,如有不妥之处欢迎指正,谢谢。

下载源码请戳这里:http://download.csdn.net/detail/baidu_23478311/9514523

时间: 2024-10-23 19:42:31

Android 实现一键切换应用主题颜色的相关文章

Android 实现一键切换应用主题颜色(二)

上一篇说到一键切换应用的主题颜色,那么今天就继续来讲一讲如何实现应用的一些图标也一样能够跟随应用的主题颜色切换而改变图标的颜色.比如应用首页的一些固定的展示图标,或者是单选框以及复选框的图标,还有一些功能按钮的图标等等.下面还是老规矩,先上一个效果图(有图有真相有木有?) 上面效果图中已经一目了然了,点击选中下面的图标后,然后再切换相应的应用主题颜色时,可以看到下面所选中的图标也会立即跟随应用的主题颜色进行切换.实现这个功能其实也很简单,不需要把每个颜色的图标都准备一套,一套就足矣了.只不过这一

Android 之夜间模式(多主题)的实现思路

实现思路 多数App由于历史原因当对其进行夜间模式的功能改造时,工作量是比较大的,所以在真正开始着手实现前,我们还是应该先明确夜间模式(多主题)到底有多少实现的思路以及它们的优劣,这样才可以有效的避免项目延期的情况出现. 自定义attr属性. 这是最基础的方法,就是通过自定义attr属性,在不同的theme中进行不同的实现,然后在layout和style中调用.这种方法改代码改动量比较大,而且根据不同的主题,drawable(5.0以上不用),selector等xml文件必须要相应的定义多份,因

从零开始学android&lt;ImageSwitcher图片切换组件.二十六.&gt;

ImageSwitcher组件的主要功能是完成图片的切换显示,例如用户在进行图片浏览的时候,可以通过按钮点击一张张的切换显示的图片,而且使用ImageSwitcher组件在每次切换的时候也可以为其增加一些动画的效果,此类定义如下: java.lang.Object ? android.view.View ? android.view.ViewGroup ? android.widget.FrameLayout ? android.widget.ViewAnimator ? android.wid

修改Kali&#160;Linux&#160;2020.1主题颜色

修改Kali Linux 2020.1主题颜色 Kali Linux 2020.1安装后,默认主题颜色为Kali-Dark.用户使用的图形界面工具,界面颜色也都是黑乎乎,很多人都不喜欢.这里将分别介绍下修改主题颜色的方法: (1)如果用户安装的是XFCE桌面,可以切换为kali-undercover主题,类似Windows 10桌面.执行命令如下所示:kali-undercover (2)如果是GNOME桌面,用户则需要手动修改外观颜色.执行命令如下所示:gnome-tweaks执行以上命令后,

android:修改PagerTabStrip中的背景颜色,标题字体的样式、颜色和图标以及指示条的颜色

1.修改PagerTabStrip中的背景颜色 我们在布局中直接设置background属性即可: <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="fill_parent" android:layout_height="fill_parent" > <android.support.v4.view.PagerTabS

180多个数据库版本一键切换,PHPWAMP8.8.8.8(支持切换任意数据库,全面支持mysql等常见数据库)

PHPWAMP8.8.8.8版本支持一键切换数据库的PHP集成环境,纯绿色 支持切换任意数据库,默认全面支持mysql等常见数据库) 最新最旧版本的数据库都可以切换,同时运行不同版本的数据库! 完美兼容任何集成环境,多开,群开无压力,满足各种变态测试! 只需点击相关设置,切换你想要的任意版本即可,真正的一键自定义! 在一键自定义同时,完美兼顾用户的自主修改,各种DIY自定义 1.支持一键自定义设置MYSQL版本,180多个MYSQL历史版本随意切换! 2.优化旧版本的"700多个PHP版本随意切

Android Studio -修改LogCat的颜色

Android Studio -修改LogCat的颜色 author:Kang,Leo weibo:http://weibo.com/kangyi 效果图 设置 Preference->Editor->Colors &n Fonts->Android Logcat 在后面将Use Inberited attributes 去掉勾选 再将 Foreground 前的复选框选上,就可以双击后面的框框去选择颜色了 Apply–>OK  推荐色值 Log级别 色值 VERBOSE

Android横竖屏切换及其对应布局加载问题

第一,横竖屏切换连带横竖屏布局问题: 如果要让软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局. 可以通过以下两种方法来切换布局: 1)在res目录下建立layout-land和layout-port目录,相应的layout文件名不变,比如:layout-land是横屏的layout,layout-port是竖屏的layout,其他的不用管,横竖屏切换时程序调用Activity的onCreate方法中的setOnContent(xxx),并自动加载相应的布局. 2)假如布

Android中Activity切换时共享视图元素的切换动画(4.x兼容方案)

同时发布在我的博客 点此进入 开始 上一篇讲了使用 Google 的 AppCompat-v7 来实现 Activity 切换时实现共享视图元素的切换动画.这一篇介绍两个可以兼容 4.x 的两个第三方方案. 上一篇:Android中Activity切换时共享视图元素的切换动画(5.0以上) 方案一:PreLollipopTransition 首先在 build.gradle 配置文件添加这个库依赖 dependencies { compile 'com.kogitune:pre-lollipop