設計師辛辛苦苦做出設計稿,開發人員辛辛苦苦把UI調好了,但是在Android用戶修改系統的默認字體大小,原先的設計很容易失效,變得非常難看,考慮你的用戶人羣,又不想因爲用戶變更默認字體大小導致app的樣式走樣,我們可以這麼做:
1.字體使用dp/dip代替sp
dp/dip(device independent pixels):一種基於屏幕密度的抽象單位。在每英寸160點的顯示器上,1dp=1px。不同設備有不同的顯示效果,這個和設備硬件有關。
sp(Scaled Pixels):主要用於字體顯示,與刻度無關的一種像素,與dp類似,但是可以根據用戶的字體大小首選項進行縮放。
查看TextView的源碼可以發現:
/**
* Set the default text size to the given value, interpreted as "scaled
* pixel" units. This size is adjusted based on the current density and
* user font size preference.
*
* @param size The scaled pixel size.
*
* @attr ref android.R.styleable#TextView_textSize
*/
@android.view.RemotableViewMethod
public void setTextSize(float size) {
setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}
/**
* Set the default text size to a given unit and value. See {@link
* TypedValue} for the possible dimension units.
*
* @param unit The desired dimension unit.
* @param size The desired size in the given units.
*
* @attr ref android.R.styleable#TextView_textSize
*/
public void setTextSize(int unit, float size) {
Context c = getContext();
Resources r;
if (c == null)
r = Resources.getSystem();
else
r = c.getResources();
setRawTextSize(TypedValue.applyDimension(
unit, size, r.getDisplayMetrics()));
}
private void setRawTextSize(float size) {
if (size != mTextPaint.getTextSize()) {
mTextPaint.setTextSize(size);
if (mLayout != null) {
nullLayouts();
requestLayout();
invalidate();
}
}
}
TypedValue.applyDimension()源碼如下:
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
dp與sp的換算差別只在於metrics.density和metrics.scaledDensity,
/**
* A scaling factor for fonts displayed on the display. This is the same
* as {@link #density}, except that it may be adjusted in smaller
* increments at runtime based on a user preference for the font size.
*/
public float scaledDensity;
因此,sp和dp的區別是乘以一個scale。
2.通過重寫系統方法禁用
在Application重寫以下方法即可
@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;
}
通過重寫方法,把fontScale重置爲默認值。此方式無侵入,僅對當前App有效。
可結合 一種極低成本的Android屏幕適配方式來看
歡迎愛學習的小夥伴加羣一起進步:230274309 。 一起分享,一起進步!少划水,多曬乾貨!!歡迎大家!!!(進羣潛水者勿加) |