Android的设备很多,适配是个大坑。所以才有了dp、sp这样的尺寸单位来适应不同的屏幕密度。他们之间的换算也并不复杂。
然而问题来了,UI那边提交来的设计图一般都是标的px。(他们并不太可能知道需要多少的dp或者sp,是吧。)咱不能每次都给他算一遍再标成dp或者sp啊。方便起见,我们需要一个自动换算的TextView,我们只需要传入设计图标注的屏幕大小和字体大小就可以适配不同设备了。
现在我们来搞一下这个小工具。
1.首先,我们需要一个自定义的属性来代替原先的字体大小属性
在values中创建一个attrs.xml文件,创建一个叫textSizePx的属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ScaleTextView">
<attr name="textSizePx" format="integer" />
</declare-styleable>
</resources>
2.接下来我们定义自己的TextView
public class ScaleTextView extends TextView {
public ScaleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray type = context.obtainStyledAttributes(attrs,R.styleable.ScaleTextView);//获得属性值
int i = type.getInteger(R.styleable.ScaleTextView_textSizePx, 25);
setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSize(i));
}
/**
* 获取当前手机屏幕分辨率,然后根据和设计图的比例对照换算实际字体大小
* @return
*/
private int getFontSize(int textSize) {
DisplayMetrics dm = new DisplayMetrics();
WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(dm);
int screenHeight = dm.heightPixels;
int rate = (int) (textSize * (float) screenHeight / 1280);//请注意这里的1280数值,一会我们还要加工一下
return rate;
}
}
布局文件里使用这个view代替原来的TextView
<util.ScaleTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New World!"
app:textSizePx="100"/>
其中的app:textSizePx的值就可以直接写设计图上的px。
来看一下效果:
device-2017-12-01-170104.png
"hello world"用的是TextView,而"New World"用的是ScaleTextView。可以看到用ScaleTextView的大小非常接近了。
3.不要满足,我们要根据设计图定大小的不是?
通常设计图不会给你标注各种屏幕下的不同数值。接下来我们就要传入设计图的屏幕大小来让字体按比例显示。
先来增加个属性baseScreenHeight(其实用宽度也是可以的,这不重要):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ScaleTextView">
<attr name="baseScreenHeight" format="integer"/>
<attr name="textSizePx" format="integer" />
</declare-styleable>
</resources>
修改一下布局的属性,baseScreenHeight和textSizePx的值就是设计图上标注的屏幕高度和字体大小:
<util.ScaleTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New World!"
app:baseScreenHeight="1280"
app:textSizePx="100"/>
然后在ScaleTextView中通过context.obtainStyledAttributes获得它
public ScaleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray type = context.obtainStyledAttributes(attrs,R.styleable.ScaleTextView);//获得属性值
int i = type.getInteger(R.styleable.ScaleTextView_textSizePx, 25);
baseScreenHeight = type.getInteger(R.styleable.ScaleTextView_baseScreenHeight, 720);
setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSize(i));
}
/**
* 获取当前手机屏幕分辨率,然后根据和设计图的比例对照换算实际字体大小
* @param textSize
* @return
*/
private int getFontSize(int textSize) {
DisplayMetrics dm = new DisplayMetrics();
WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(dm);
int screenHeight = dm.heightPixels;
Log.d("LOGCAT","baseScreenHeight"+baseScreenHeight);
int rate = (int) (textSize * (float) screenHeight / baseScreenHeight);
return rate;
}
完工,从此你只要照抄设计图的尺寸就好了。
加个餐:TextView表示中文的加粗要在代码里设置,这个相当不便。所以,我们给他加上加粗的属性。
arrt.xml文件中添加textBold属性
<declare-styleable name="ScaleTextView">
<attr name="baseScreenHeight" format="integer"/>
<attr name="textSizePx" format="integer" />
<attr name="textBold" format="boolean" />
</declare-styleable>
自定义的ScaleTextView里设置加粗
boolean _isBold=type.getBoolean(R.styleable.ScaleTextView_textBold, false);
getPaint().setFakeBoldText(_isBold);
以后在布局文件中就可以直接使用app:textBold="true"
设置加粗了。
网友评论