仿微信调整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