生活随笔
收集整理的這篇文章主要介紹了
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设置字重(自定义自重)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。