Android实现皮肤主题修改

文章介绍了如何实现App内的皮肤切换功能,通过为不同主题的图片添加特定后缀,然后使用工具类动态获取对应主题的资源ID。代码示例展示了如何根据当前主题类型替换图片和颜色资源,以及如何设置布局以适应多主题。此外,还提供了设置字体和背景颜色的方法,以及对话框参数的调整。
摘要由CSDN通过智能技术生成

最近在做App内皮肤切换功能,想了很久方案,写了个皮肤更换工具类,适配N+皮肤种类。

话不多说,直接捋一下我的设计思路,因为我的App默认为黑色主题,因此在做其他皮肤主题时,我的图片命名方式是直接添加后缀。

比如默认主题(黑色)的图片名成为menu。白色主题就叫menu_white  科技主题叫menu_tech,我用的是Mac电脑,设计师做好图后直接批量命名。操作方式如下

白色主题的图片是设计师给我的,命名跟默认主题是一致,则只需要全选图片或者selecter或者shape  右键选择重命名,选择以添加文本方式如图

 

这样所有白色主图的图片都有个white后缀,其他主题也可按照此类方法操作

再结合工具类方法,代码如下

 

    public static int getResourceId(int drawableId){
        String name = SLCApplication.getAppContext().getResources().getString(drawableId);
//        上面转换出来路径为: res/drawable-xhdpi-v4/user_vip.png
//        Log.e(TAG, "getResourceId: name===="+name );
        //得到user_vip.png这个图片名称的字符串
        name = name.substring(name.lastIndexOf("/")+1);
//        Log.e(TAG, "getResourceId: nam0="+name );
        //user_vip.png替换成user_vip_white并去掉.png的后缀
        int themeType = (int)SpUtils.get(SLCApplication.getAppContext(), SkinActivity.THEME_TYPE_KEY,1);
//        Log.e(TAG, "getResourceId: themeType="+themeType );
        if (themeType == 0){
            name = name.replace(name.substring(name.lastIndexOf(".")), "_white");
        }else if (themeType == 2){
            name = name.replace(name.substring(name.lastIndexOf(".")), "_tech");
        }else if (themeType == 3){
            name = name.replace(name.substring(name.lastIndexOf(".")), "_retro");
        }else {
            name = name.replace(name.substring(name.lastIndexOf(".")), "");
        }
//        Log.e(TAG, "getResourceId: name="+name );
        int ids = SLCApplication.getAppContext().getResources().getIdentifier(name,"drawable",SLCApplication.getAppContext().getPackageName());
        if (ids == 0){
            return drawableId;
        }
        return ids;
    }

    public static int getColor(Context context, int colorResId) {
        TypedValue typedValue = new TypedValue();
        TypedArray typedArray = context.obtainStyledAttributes(typedValue.data, new int[] {colorResId});
        int color = typedArray.getColor(0, 0);
        typedArray.recycle();
        return color;
    }
getResourceId方法是通过图片Id 返回对应主题的Id  ,getColor则是设置成为什么颜色。

设置字体方法调用如下:

text_title.setTextColor(ColorAPI.getColor(this, R.attr.whiteColor));

设置图片方法调用如下:

menuImage.setImageDrawable(getDrawable(ColorAPI.getResourceId(R.drawable.menu_selector)));

布局调用如下:

这样的写法是由于我们设置了多主题,可以去自动适配  主题写法如下

在res-->values包中的attrs.xml中的添加颜色属性  如下图

在res-->values包中的styles.xml中的设置主题并设置颜色属性的值如下图

由于我的整个项目的Activity都是继承与自Base ,则只需要在Base的OnCreate方法setContentView函数之前设置好主题,则可以进行自动适配

如图

 

 

工具类中还有几个适配主题的其他方法 ,我整理了下 ,整个类的源码如下

/**
 * ColorAPI
 * Create by lxy on 5/6/23 4:54 PM
 * Copyright © 2022 lxy. All rights reserved.
 **/
public class ColorAPI {

    private static final String TAG = "ColorAPI";

    public static int getResourceId(int drawableId){
        String name = SLCApplication.getAppContext().getResources().getString(drawableId);
//        上面转换出来路径为: res/drawable-xhdpi-v4/user_vip.png
//        Log.e(TAG, "getResourceId: name===="+name );
        //得到user_vip.png这个图片名称的字符串
        name = name.substring(name.lastIndexOf("/")+1);
//        Log.e(TAG, "getResourceId: nam0="+name );
        //user_vip.png替换成user_vip_white并去掉.png的后缀
        int themeType = (int)SpUtils.get(SLCApplication.getAppContext(), SkinActivity.THEME_TYPE_KEY,1);
//        Log.e(TAG, "getResourceId: themeType="+themeType );
        if (themeType == 0){
            name = name.replace(name.substring(name.lastIndexOf(".")), "_white");
        }else if (themeType == 2){
            name = name.replace(name.substring(name.lastIndexOf(".")), "_tech");
        }else if (themeType == 3){
            name = name.replace(name.substring(name.lastIndexOf(".")), "_retro");
        }else {
            name = name.replace(name.substring(name.lastIndexOf(".")), "");
        }
//        Log.e(TAG, "getResourceId: name="+name );
        int ids = SLCApplication.getAppContext().getResources().getIdentifier(name,"drawable",SLCApplication.getAppContext().getPackageName());
        if (ids == 0){
            return drawableId;
        }
        return ids;
    }

    public static int getColor(Context context, int colorResId) {
        TypedValue typedValue = new TypedValue();
        TypedArray typedArray = context.obtainStyledAttributes(typedValue.data, new int[] {colorResId});
        int color = typedArray.getColor(0, 0);
        typedArray.recycle();
        return color;
    }

    public  @interface FrameType {
        int BOTTOM = 0; //底部按钮
        int BOTTOM_LEFT_RIGHT = 1;//底部左右两边按钮
        int FRAME_TWO = 2; //弹出框2行
        int FRAME_THREE = 3;//弹出框3行
    }
    public static void setDrawable(Context context, int type, View textView) {
        //type 0:底部框  1:弹出框底部(取消、确定)
        int themeType = (int) SpUtils.get(context, SkinActivity.THEME_TYPE_KEY,1);
        if (themeType !=2 && themeType !=3)return;
        if (textView.getClass().equals(TextView.class) || textView.getClass().equals(Button.class)){
            ((TextView) textView).setTextColor(getColor(context, R.attr.whiteColor));
        }
        if (themeType == 2){
            if (type == FrameType.BOTTOM)
                 textView.setBackground(context.getDrawable(R.drawable.btn_bottom_frame_tech));
            else if (type == FrameType.BOTTOM_LEFT_RIGHT)
                textView.setBackground(context.getDrawable(R.drawable.btn_frame_tech));
            else if (type == FrameType.FRAME_TWO)
                textView.setBackground(context.getDrawable(R.drawable.tip_frame_tech));
            else if (type == FrameType.FRAME_THREE)
                textView.setBackground(context.getDrawable(R.drawable.new_create_frame_tech));
        }else if (themeType == 3){
            if (type == FrameType.BOTTOM)
                textView.setBackground(context.getDrawable(R.drawable.btn_bottom_frame_retro));
            else if (type == FrameType.BOTTOM_LEFT_RIGHT)
                textView.setBackground(context.getDrawable(R.drawable.btn_frame_retro));
            else if (type == FrameType.FRAME_TWO)
                textView.setBackground(context.getDrawable(R.drawable.tip_frame_retro));
            else if (type == FrameType.FRAME_THREE)
                textView.setBackground(context.getDrawable(R.drawable.new_create_frame_retro));
        }
    }

    public static void setDialogParam(Context context, AlertDialog builder) {
        WindowManager.LayoutParams lp = builder.getWindow().getAttributes();
        lp.gravity = Gravity.CENTER;
        lp.width =  context.getResources().getDisplayMetrics().widthPixels-Util.dip2px(context, 50);
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        builder.getWindow().setAttributes(lp);
    }
}

文章分享给大家不容易,转载请注明出处!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值