欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  互联网

仿微信调整APP文本大小

程序员文章站 2022-06-26 13:11:08
仿微信调整APP文本大小调整今日要实现类型微信,qq的文本大小调整,不随系统变化,目前网上主要方案有:1、设置fontScale2、设置densityDpi3、设置theme观察微信调整文本大小时,头像等元素也随着变化,因此排除fontScale模式,设置theme模式需要修改的代码太多,也不适用,排除,因此选择方案2具体实现如下:Activity基类中添加: @Override public Resources getResources() { Resourc...

仿微信调整APP文本大小

今日要实现类型微信,qq的文本大小调整,不随系统变化,目前网上主要方案有:
1、设置fontScale
2、设置densityDpi
3、设置theme
观察微信调整文本大小时,头像等元素也随着变化,因此排除fontScale模式,设置theme模式需要修改的代码太多,也不适用,排除,因此选择方案2
具体实现如下:

Activity基类中添加:

    @Override
    public Resources getResources() {
        Resources resources = super.getResources();
        return DisplayUtils.getResources(this, resources);
    }

	//主要用于解决fragment中不跟随变化的我那天
    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(getAttachBaseContext(newBase));
    }

    protected Context getAttachBaseContext(Context newBase) {
        return DisplayUtils.attachBaseContext(newBase);
    }


DisplayUtils代码

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.util.Log;
import android.view.Display;

import com.sogou.xiaop_android.business.model.dao.entity.KeyValuePair;

import java.lang.reflect.Method;

public class DisplayUtils {

    public static float fontScale = -1f;
    public static float sysScale = 1f;

    public static float usedScale;
    private static int sysDpi;
    private static int defaultDpi;
    private static float dpiScale;

    private static int usedDpi;

    private static void initFontScale(Configuration configuration) {
        if (fontScale == -1) {
            fontScale = KeyValuePair.getPreferFloat(KeyValuePair.KEY_FONT_SCALE_SIZE, 1.0f);
            sysScale = configuration.fontScale;
            defaultDpi = getDefaultDisplayDensity();
            sysDpi = configuration.densityDpi;
            if (sysScale == 0) {
                sysScale = 1f;
            }
            if (sysDpi > 0 && defaultDpi > 0) {
                dpiScale = (sysDpi - defaultDpi) / ((float) defaultDpi);
            }
        }
        if (fontScale == 1f) {
            if (sysScale != 1f) {
                usedScale = fontScale + (sysScale - 1f) / 4;
            } else if (sysDpi != defaultDpi) {
                usedScale = fontScale + dpiScale / 4;
            } else {
                usedScale = 1f;
            }
        } else {
            usedScale = fontScale;
        }
        usedDpi = (int) (defaultDpi * usedScale);
        Log.i("DisplayUtils", "initFontScale usedDpi " + usedDpi + ",defaultDpi " + defaultDpi + ",sysDpi=" + sysDpi + ",fontScale=" + fontScale + ",usedScale=" + usedScale + ",sysScale=" + sysScale);
    }

    public static int getDefaultDisplayDensity() {
        try {
            Class clazz = Class.forName("android.view.WindowManagerGlobal");
            Method method = clazz.getMethod("getWindowManagerService");
            method.setAccessible(true);
            Object iwm = method.invoke(clazz);
            Method getInitialDisplayDensity = iwm.getClass().getMethod("getInitialDisplayDensity", int.class);
            getInitialDisplayDensity.setAccessible(true);
            Object densityDpi = getInitialDisplayDensity.invoke(iwm, Display.DEFAULT_DISPLAY);
            Log.d("DisplayUtils", "densityDpi: " + densityDpi);
            return (int) densityDpi;
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    /**
     * 系统设置"显示大小"时原有UI样式保持不变:
     * <p>
     * 1、当调节手机系统"显示大小"【调大】的时候,相应的dpi会变大【dp = (dpi/160) * px】,此时dp就会变大,所以相应的UI布局就会变大。
     * 2、当调节手机系统"分辨率"【调小】的时候,相应的dpi会变小【比如由480-->320】。如果此时使用技术手段使dpi保持不变,那么相同的dp就会占用更多的px,所以UI布局就会变大。
     *
     * @param context
     */
    public static void setDefaultDisplay(Context context) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
            Configuration origConfig = context.getResources().getConfiguration();
            //获取手机出厂时默认的densityDpi【注释1】
            origConfig.densityDpi = getDefaultDisplayDensity();

            Log.d("DisplayUtils", "densityDpi: " + origConfig.densityDpi);
            context.getResources().updateConfiguration(origConfig, context.getResources().getDisplayMetrics());
        }
    }

    /**
     * 保持字体大小不随系统设置变化(用在界面加载之前)
     * 要重写Activity的attachBaseContext()
     */
    public static Context attachBaseContext(Context context) {

        Configuration config = context.getResources().getConfiguration();
        initFontScale(config);
        if (usedDpi > 0) {
            config.fontScale = 1f;
            config.densityDpi = usedDpi;
        } else {
            config.fontScale = usedScale;
        }
        return context.createConfigurationContext(config);
    }

    /**
     * 保持字体大小不随系统设置变化(用在界面加载之前)
     * 要重写Activity的getResources()
     */
    public static Resources getResources(Context context, Resources resources) {

        Configuration config = resources.getConfiguration();
        initFontScale(config);

        if ((usedDpi > 0 && (config.densityDpi != usedDpi || config.fontScale != 1f)) || (config.fontScale != usedScale)) {
            if (usedDpi > 0) {
                config.fontScale = 1f;
                config.densityDpi = usedDpi;
            } else {
                config.fontScale = usedScale;
            }
            return context.createConfigurationContext(config).getResources();
        } else {
            return resources;
        }
    }
}

设置完成字体后重启APP刷新:

 Intent intent = new Intent();
        intent.setClass(AppEnvVars.appContext, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK| Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);

        Activity curActivity = AppEnvVars.getCurrentActivity();
        (curActivity == null ? AppEnvVars.appContext : curActivity).startActivity(intent);

本文地址:https://blog.csdn.net/weixin_43845112/article/details/107544917

相关标签: android java