生活随笔
收集整理的这篇文章主要介绍了
TextView设置字重(自定义自重)
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
TextView自定义加粗
- 1、目的
- 2、三种加粗方法
- 3、第三种方式额外问题以及解决方案
1、目的
android提供的几种加粗方法不满足我司ui设计的字体字重
2、三种加粗方法
设置TextView的textStyle为Bold,这种方式的textView很粗
xml:android:textStyle="bold"
代码:paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
代码设置FakeBoldText,这种方式加粗过的比较接近medium效果
paint
.setFakeBoldText(true)
如果以上都不满足ui小姐姐,我们还可以换种思路,TextView的加粗其实本质就是画笔paint的粗细,我们可以通过设置画笔的宽度来满足需求
paint
.setStrokeWidth(8f);
paint
.setStyle(Paint.Style.FILL_AND_STROKE
);
(设置Style为FILL_AND_STROKE的目的是:如果字体过大,填充模式为STROKE的话就会出现字画之间的漏洞,设置FILL不会有效果,如图)
STOKE模式:
FIll模式:
3、第三种方式额外问题以及解决方案
问题:
1、每个TextView都这样设置的话,重复代码太多
2、字重之间没有一个衡量单位标准
3、字号大小不同需要设置不同的StrokeWidth,如果不设置,小字号看起来很粗,大字号看起来没效果
解决方案:
1、继承LayoutFactory2(每个view创建的地方),在xml里面自定义设置一个额外属性,如果有地方需要自定义自重,使用该属性设置
2、与自家ui小姐姐商讨确定字重的等级集,比如我们公司就制定一共5个等级字重
3、根据字号以及等级,设计一套计算规则来计算出StrokeWidth
3.1实现细节
在xml中自定义属性textBoldStyle,枚举,定义了5个等级
<attr name="textBold" format="enum"><enum name="zero" value="0" /><enum name="one" value="1" /><enum name="two" value="2" /><enum name="three" value="3" /><enum name="four" value="4" /></attr>
在要用到的xml的文件TextVIew节点下设置该属性
<TextViewandroid:id="@+id/textView3"style="@style/TextVIewStyle"app:textBold="two" />
style属性:
<style name="TextVIewStyle"><item name="android:layout_width">match_parent</item><item name="android:layout_height">100dp</item><item name="android:gravity">center</item><item name="android:text">Hello World!你好世界!</item><item name="android:textSize">20sp</item></style>
重写LayoutFactory2,关键思想就是重写onCreateView,自己创建TextView以及TextView的子类(怎么重写?一个字,抄,抄系统源码),然后读取textBold属性,获取加粗等级,然后设计一套计算规则(我只是简单的根据字体dp进行等比放大缩小,效果还可以),得到设置画笔宽度的值
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;public class NightThemeInflaterFactory implements LayoutInflater.Factory2 {private Map<TextView, Integer> map
= new HashMap<>();private static final String NAMESPACE_RES_AUTO
= "http://schemas.android.com/apk/res-auto";private static final String[] mClassPrefixList
= {"android.widget.","android.webkit.","android.app.","android.view."};private static final Class<?>[] mConstructorSignature
= new Class[]{Context.class, AttributeSet.class};private static final HashMap<String, Constructor<? extends View>> mConstructorMap
=new HashMap<String, Constructor<? extends View>>();@Overridepublic View onCreateView(View parent
, String name
, Context context
, AttributeSet attrs
) {return onCreateView(name
, context
, attrs
);}@Overridepublic View onCreateView(String name
, Context context
, AttributeSet attrs
) {View view
= createSDKView(name
, context
, attrs
);if (null == view
) {view
= createView(name
, context
, attrs
);}if (view
instanceof TextView) {TextView textView
= (TextView) view
;int value
= attrs
.getAttributeIntValue(NAMESPACE_RES_AUTO
, "textBold", -1);if (value
== -1) {TypedArray typedArray
= context
.obtainStyledAttributes(R.style
.TextVIewStyle
, new int[]{R.attr
.textBold
});value
= typedArray
.getInt(0, -1);typedArray
.recycle();}float density
= getDensity(context
);float textSize
= textView
.getTextSize();int dp
= (int) (textSize
/ density
);float fullNums
= dp
/ 20f;value
= Math.min(value
, 4);float targetLevel
= fullNums
* value
;if (value
> -1 && textView
.getTypeface().getStyle() != Typeface.BOLD
) {textView
.getPaint().setStrokeWidth(targetLevel
);textView
.getPaint().setStyle(Paint.Style.FILL_AND_STROKE
);map
.put(textView
, value
);}}return view
;}public void generateTvBold(float percent
, Context context
) {float density
= getDensity(context
);TextView textView
= null;for (Map.Entry<TextView, Integer> entry
: map
.entrySet()) {textView
= entry
.getKey();float textSize
= textView
.getTextSize();int dp
= (int) (textSize
/ density
);float fullNums
= dp
/ percent
;int value
= entry
.getValue();float targetLevel
= fullNums
* value
;textView
.getPaint().setStrokeWidth(targetLevel
);textView
.getPaint().setStyle(Paint.Style.FILL_AND_STROKE
);textView
.invalidate();}}private View createSDKView(String name
, Context context
, AttributeSetattrs
) {if (-1 != name
.indexOf('.')) {return null;}for (int i
= 0; i
< mClassPrefixList
.length
; i
++) {View view
= createView(mClassPrefixList
[i
] + name
, context
, attrs
);if (view
!= null) {return view
;}}return null;}private View createView(String name
, Context context
, AttributeSetattrs
) {Constructor<? extends View> constructor
= findConstructor(context
, name
);try {return constructor
.newInstance(context
, attrs
);} catch (Exception e
) {}return null;}private Constructor<? extends View> findConstructor(Context context
, String name
) {Constructor<? extends View> constructor
= mConstructorMap
.get(name
);if (constructor
== null) {try {Class<? extends View> clazz
= context
.getClassLoader().loadClass
(name
).asSubclass(View.class);constructor
= clazz
.getConstructor(mConstructorSignature
);mConstructorMap
.put(name
, constructor
);} catch (Exception e
) {}}return constructor
;}private float getDensity(Context context
) {return context
.getResources().getDisplayMetrics().density
;}}
在activity的onCreate函数的setContentView之前设置使用我们自定义的layoutFactory2
@Overrideprotected void onCreate(Bundle savedInstanceState
) {LayoutInflaterCompat.setFactory2(getLayoutInflater(), CustomFactory());super.onCreate(savedInstanceState
);setContentView(R.layout
.activity_main
);}
总结
以上是生活随笔为你收集整理的TextView设置字重(自定义自重)的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。