小记
记录下一些很少用到的小知识点,和一些自己写的bug。
设置字号大小固定
有时候当用户调整系统字号的时候,页面布局可能非常难看了。
需要设置固定字号大小的方法如下:
public static void onMakeFontsSteady(Context context) {
try {
Resources resource = context.getResources();
Configuration c = resource.getConfiguration();
c.fontScale = 1.0f;
resource.updateConfiguration(c, resource.getDisplayMetrics());
} catch (Exception exception) {
Log.d("Tinker.ApplicationLike","报错");
}
}
一般在自定义的Application
的onCreate()
方法初始化。
但是一般没啥效果,需要以activity纬度才能其效果,所以可以activity的基类或者如下:
//在Application中
private void initFontsSize() {
this.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
onMakeFontsSteady(activity);
}
@Override
public void onActivityStarted(@NonNull Activity activity) {
}
@Override
public void onActivityResumed(@NonNull Activity activity) {
}
@Override
public void onActivityPaused(@NonNull Activity activity) {
}
@Override
public void onActivityStopped(@NonNull Activity activity) {
}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
}
});
}
后来发现,第一个页面上部分还是会出现特殊大小的字体,部分正常的,在加载fragment的情况下,还不是实时获取正确的fontScale值,所以又在activity里面加了如下方法:
activity里
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig.fontScale != 1){
//非默认值
getResources();
}
super.onConfigurationChanged(newConfig);
}
@Override
public Resources getResources() {
Resources res = super.getResources();
if (res.getConfiguration().fontScale != 1) {//非默认值
Configuration newConfig = new Configuration();
newConfig.setToDefaults();//设置默认
res.updateConfiguration(newConfig, res.getDisplayMetrics());
}
return res;
}
好像在没啥问题了,第一个页面也好了,其他页面也好了。
重启应用本身
在有些时候需要重启应用本身,比如:在测试中需求切换测试环境,选择测试环境后自动重启应用、当crash次数达到上限,清空缓存重启应用等操作。
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
//切环境清除缓存
...
...
android.os.Process.killProcess(android.os.Process.myPid());
莫名其妙的gif速率变慢
一个很奇怪的问题,用Glide
加载一个gif图,竟然在不同手机上的,gif的播放速率不一样,对,不一样。然后去找ui老哥说他图是正常的,概不负责。后来百度了下,说要添加这个库android-gif-drawable ,后来发现还有其他解决办法:反射修改glide里面GifHeader中frames的速率(牛人总是有办法的):
GlideApp.with(mContext)
.asGif()
.load(R.drawable.icon_wumaheyi_guide)
.apply(requestOptions)
.into(new SimpleTarget<GifDrawable>(){
/**
* The method that will be called when the resource load has finished.
*
* @param resource the loaded resource.
* @param transition
*/
@Override
public void onResourceReady(GifDrawable resource, Transition<? super GifDrawable> transition) {
try {
Field field = GifDecoder.class.getDeclaredField("header");
field.setAccessible(true);
GifHeader header = (GifHeader) field.get(resource.getFirstFrame());
Field field2 = GifHeader.class.getDeclaredField("frames");
field2.setAccessible(true);
List frames = (List) field2.get(header);
if (frames.size()>0){
Field delay = frames.get(0).getClass().getDeclaredField("delay");
delay.setAccessible(true);
for (Object frame : frames) {
//这里直接速率
delay.set(frame,40);
}
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
mIvGoTask.setImageDrawable(resource);
resource.setLoopCount(Integer.MAX_VALUE);
resource.start();
}
});
如果开启混淆别忘了keep:
# glide加载gif速率问题 反射更改速率
-keep class com.bumptech.glide.gifdecoder.GifHeader
-keep class com.bumptech.glide.gifdecoder.GifDecoder
-keep class com.bumptech.glide.load.resource.gif.GifDrawable
-dontwarn com.bumptech.glide.**
addFlags和setFlags
我们启动activity或者组件的时候,会添加一些flags,注意这两个区别,千万千万不要写反顺序了,比如,要启动一个activity,达到singleTask的启动模式:
当时sb了,写成如下这样,后面set直接重制了Flags。
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
看下addFlags和setFlags区别如下:
public @NonNull Intent addFlags(@Flags int flags) {
mFlags |= flags;
return this;
}
public @NonNull Intent setFlags(@Flags int flags) {
mFlags = flags;
return this;
}
所以正确写法如下:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
设置shape的描边
现在才知道shape的drawable可以代码设置描边:
TextView view = baseViewHolder.getView(R.id.btn);
GradientDrawable background = (GradientDrawable)view.getBackground();
background.setStroke(1,Color.parseColor(btnBorderColor));