日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

TextView设置字重(自定义自重)

發布時間:2023/12/31 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TextView设置字重(自定义自重) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

TextView自定義加粗

  • 1、目的
  • 2、三種加粗方法
  • 3、第三種方式額外問題以及解決方案
    • 3.1實現細節

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個等級
  • <!-- 系統TextView自定義額外屬性 --><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."};//記錄對應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);}//如果是TextView或者是繼承了TextView的子控件if (view instanceof TextView) {TextView textView = (TextView) view;//查找textBold屬性(xml中直接定義的)int value = attrs.getAttributeIntValue(NAMESPACE_RES_AUTO, "textBold", -1);//查找textBold屬性(寫在style里面的)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();//將文字大小換算成dp屬性,根據dp進行放大縮小系數int dp = (int) (textSize / density);//我的項目是以dp的1/10為最大的等級,最低等級是0即正常字體(不加粗),//然后在1/10的基礎上再劃分為4個等級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) {//我的項目是以dp的1/10為最大的等級,最低等級是0即正常字體(不加粗),//然后在1/10的基礎上再劃分為4個等級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) {//如果包含 . 則不是SDK中的view 可能是自定義view包括support庫中的Viewif (-1 != name.indexOf('.')) {return null;}//不包含就要在解析的 節點 name前,拼上: android.widget. 等嘗試去反射for (int i = 0; i < mClassPrefixList.length; i++) {View view = createView(mClassPrefixList[i] + name, context, attrs);if (view != null) {return view;}}return null;}/*** @param name* @param context* @param attrs 反射創建view* @return*/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设置字重(自定义自重)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。