您的位置:首页 > 移动开发 > Android开发

Android换肤功能实现(白天、黑夜)

2018-02-25 17:12 239 查看
Android程序中进行整体更换颜色,背景,以及图片

在应用中点击相关按钮进行切换app的整体风格,颜色,背景等内容

使用自定义控件,自定义颜色样式进行程序的颜色改变

参考博客:Android 实现切换主题皮肤功能

最终实现效果:



1、style样式文件

<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
</style>

<!--白天-->
<style name="dayTheme" parent="AppTheme">
<item name="text_bg">#0a0</item>
<item name="activity_bg">#f7f7f7</item>
<item name="text_color">#d00</item>
<item name="imgBg_main">@drawable/u534</item>
<item name="imgBg_second">@drawable/u33</item>
</style>
<!--夜晚-->
<style name="nightTheme" parent="AppTheme">
<item name="text_bg">#fff</item>
<item name="activity_bg">#1e1e2a</item>
<item name="text_color">#00a</item>
<item name="imgBg_main">@drawable/u536</item>
<item name="imgBg_second">@drawable/u44</item>
</style>
</resources>


2、attr文件 values下的attr.xml文件

<resources>
<attr name="activity_bg" format="reference|color" />
<attr name="text_bg" format="reference|color" />
<attr name="text_color" format="reference|color" />
<attr name="imgBg_main" format="integer"/>
<attr name="imgBg_second" format="integer"/>
</resources>


3、样式布局文件

这里需要通过?attr/text_bg 进行引入样式

同时使用自定义VIew

<?xml version="1.0" encoding="utf-8"?>
<com.example.a390778.testchangeicon.ThemeRelativeLayout 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:background="?attr/activity_bg"
tools:context="com.example.a390778.testchangeicon.MainActivity"
>
<com.example.a390778.testchangeicon.ThemeTextView
android:id="@+id/textView"
android:layout_width="100dip"
android:layout_height="50dip"
android:background="?attr/text_bg"
android:textColor="?attr/text_color"
android:layout_centerHorizontal="true"
android:text="切换颜色" />
<com.example.a390778.testchangeicon.ThemeButton
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:layout_width="100dip"
android:layout_height="50dip"
android:id="@+id/buttonId"
android:background="?attr/text_bg"
android:textColor="?attr/text_color"
android:text="跳转界面"
/>
<com.example.a390778.testchangeicon.ThemeImageView
android:layout_marginTop="300dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="?attr/imgBg_main"
/>
</com.example.a390778.testchangeicon.ThemeRelativeLayout>


4、MainActivity的写法

public class MainActivity extends Activity {

private TextView tv;
private View view;
private Button buttonId;
@Override
protected void onCreate(Bundle savedInstanceState) {
//判断偏好设置中当前的值
if(SharedUtil.getShartData(this,"name").equals("0")){
SharedUtil.setShartData(this,"day");
}
if(SharedUtil.getShartData(this,"name").equals("night")){
//设置夜晚主题  需要在setContentView之前
setTheme(R.style.nightTheme);
}else{
//设置白天主题
setTheme(R.style.dayTheme);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

view = this.findViewById(R.id.activity_main);
tv = (TextView) this.findViewById(R.id.textView);
buttonId = (Button) this.findViewById(R.id.buttonId);
buttonId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//我们先取这个根布局的 bitmap缓存
view.setDrawingCacheEnabled(true);
view.buildDrawingCache(true);
final Bitmap localBitmap=Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
if(SharedUtil.getShartData(MainActivity.this,"name").equals("night")){
SharedUtil.setShartData(MainActivity.this,"day");
//重启activity实现
//                    recreate();
setTheme(R.style.dayTheme);
}else{
SharedUtil.setShartData(MainActivity.this,"night");
//                    recreate();
setTheme(R.style.nightTheme);
}
/**
*  我们new出来的这个临时蒙版view --
*  tempView就把他放到跟布局view里面
并且让他充满 同时这个view的background就是截屏前我们的那个截图bitmap
*/
final View tempView = new View(getApplicationContext());
tempView.setBackground(new BitmapDrawable(getResources(),localBitmap));
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
((ViewGroup)view).addView(tempView,params);
tempView.animate().alpha(0).setDuration(400).setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
//这个方法就是实现不重启页面切换主题的
ThemeUIUtil.changeTheme(view,getTheme());
}
@Override
public void onAnimationEnd(Animator animation) {
((ViewGroup)view).removeView(tempView);
localBitmap.recycle();
}
@Override
public void onAnimationCancel(Animator animation) {
}

@Override
public void onAnimationRepeat(Animator animation) {
}
}).start();
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}


5、需要的工具类 SharedUtil

public class SharedUtil {

/**
* 拿去参数偏好设置
* @param context
* @param name
* @return
*/
public static String getShartData(Context context,String name) {
String temp = context.getSharedPreferences("ssun",context.MODE_PRIVATE).getString(name,"0");
Log.e("getData:",temp);
return temp;
}

/**
* 保存参数
* @param name
*/
public static void setShartData(Context context,String name){
SharedPreferences preferences  = context.getSharedPreferences("ssun", Context.MODE_PRIVATE);
SharedPreferences.Editor edit = preferences.edit();
edit.putString("name", name);
edit.commit();
}
}


ViewAttributeUtil

public class ViewAttributeUtil {
public static int getAttributeValue(AttributeSet attr,int paramInt){
int value = -1;
int count = attr.getAttributeCount();
for(int i=0;i<count;i++){
if(attr.getAttributeNameResource(i) == paramInt){
String str = attr.getAttributeValue(i);
if(null!=str && str.startsWith("?")){
value = Integer.valueOf(str.substring(1,str.length())).intValue();
return value;
}
}
}
return value;
}
public static int getBackgroundAttribute(AttributeSet attr){
return getAttributeValue(attr,android.R.attr.background);
}
public static int getTextColorAttribute(AttributeSet attr){
return getAttributeValue(attr,android.R.attr.textColor);
}
public static int getImageViewAttribute(AttributeSet attr){
return getAttributeValue(attr,android.R.attr.src);
}

public static void applyimageViewDrawable(ThemeUIInterface ci, Resources.Theme theme,int paramInt){
TypedArray ta = theme.obtainStyledAttributes(new int[]{paramInt});
int res = ta.getResourceId(0,0);
if(null != ci){
((ImageView)ci.getView()).setImageResource(res);
}
ta.recycle();
}

public static void applyBackgroundDrawable(ThemeUIInterface ci, Resources.Theme theme,int paramInt){
TypedArray ta = theme.obtainStyledAttributes(new int[]{paramInt});
Drawable drawable = ta.getDrawable(0);
if(null != ci){
(ci.getView()).setBackground(drawable);
}
ta.recycle();
}
public static void applyTextDrawable(ThemeUIInterface ci, Resources.Theme theme,int paramInt){
TypedArray ta = theme.obtainStyledAttributes(new int[]{paramInt});
int resourceId = ta.getColor(0,0);
if(null != ci && ci instanceof TextView){
((TextView)ci.getView()).setTextColor(resourceId);
}
ta.recycle();
}
}


ThemeUIUtil

public class ThemeUIUtil {
/**
* 切换应用主题
*/
public static void changeTheme(View rootView, Resources.Theme theme){
//就是递归调用changeTheme-----递归调用setTheme了
if(rootView instanceof ThemeUIInterface){
((ThemeUIInterface)rootView).setTheme(theme);
if(rootView instanceof ViewGroup){
int count = ((ViewGroup) rootView).getChildCount();
for(int i =0 ;i<count;i++){
changeTheme(((ViewGroup) rootView).getChildAt(i),theme);
}
}
}
}
}


接口ThemeUIInterface

public interface ThemeUIInterface {
View getView();
void setTheme(Resources.Theme theme);
}


6、自定义View

其他自定义视图与ThemeRelativeLayout类似

public class ThemeRelativeLayout extends RelativeLayout implements  ThemeUIInterface{

private int attr_background = -1;
public ThemeRelativeLayout(Context context) {
super(context);
}

public ThemeRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.attr_background =ViewAttributeUtil.getBackgroundAttribute(attrs);
}

public ThemeRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.attr_background =ViewAttributeUtil.getBackgroundAttribute(attrs);
}

@Override
public View getView() {
return this;
}

@Override
public void setTheme(Resources.Theme theme) {
if(attr_background != -1){
ViewAttributeUtil.applyBackgroundDrawable(this,theme,attr_background);
}
}
}


换肤基本结束

如果使用recreate();换肤相对简单,直接使用该方法即可实现,该方法通过重启activity进行换肤,简单更换可以使用。

项目下载地址:

http://download.csdn.net/download/u013009808/10258564

解压进行导入就可以使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: