[置顶] 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

你可能感兴趣的:(切换应用主题,Android应用主题,一键切换主题,应用主题颜色)