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

版权声明:个人原创文章,欢迎点评,有错希望指出来,新手,谢谢大家--。-- https://blog.csdn.net/u013009808/article/details/79369589

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
解压进行导入就可以使用

猜你喜欢

转载自blog.csdn.net/u013009808/article/details/79369589