Android进阶之路 - 字体加粗,定制化字体粗度
在客户端中不论是PC端,还是移动端主要价值之一就体现在用户交互方面,也就是用户体验了,接下来讲的是很常见的字体加粗问题
UI大找茬
- 深入浅出字体、字体库
- TextView文本渐变
- 字体阴影、文字阴影
- 字体加粗 - 定制化字体粗度
在开发中经常会遇到设计说某个文本字体粗度不对,需要重一点,或者轻一点,这时候当系统控件原属性不满足需求时,就需要我们定制化处理一下
- 基础讲解
- 系统自带 - 原始版(粗度固定,无扩展)
- 自定义控件 - 基础版(扩展不足,基本够用)
- 优化前
- 优化后
- 使用方式
- 静态设置
- 动态设置
- 自定义控件 - 进阶版(推荐:可自行扩展,定制化高)
- 仅支持动态设置
- 支持动态、静态设置
- 静态设置
- 动态设置
虽然看起来写了不少,但其实核心只在于获取当前控件的 Paint(画笔)后重新设置strokeWidth、style属性 ,然后重新绘制即可!
tip:差点忘记说了,如果通过该篇未满足你的诉求,你可以看一下设计是否使用了字体库,一般字体库也会提供常规字体和加粗字体,关于字体库方面的知识,可以直接前往 深入浅出字体、字体库
基础讲解
设计比较喜欢拿 Android 与 IOS 做对比,所以经常会遇到一些 IOS 分分钟解决的问题,Android 却需要花多倍的时间来处理,以前经常会遇到 1 IOS = 1.5||2 Android 的场景,现在这环境可能比较这样的场景也比较少咯
关于字体粗度的实际设置,主要是在体现其 字重(字体粗细),因字重等级不同,带来的效果也有所不同
Andoird 提供的字体粗度主要有俩种
- normal 默认正常字体(0)
- bold 加粗字体(1)
相对于Android 提供的 regular-400,bold-700 两种字重(设置600以下均以400字重效果来显示;设置700才会显示出加粗文字)- 源码中常以 0 - 1设置字重 ;iOS系统原生字体字重等级全面,从100-600都有,效果也更全一些,网上找了一个对比图如下

由于 Andoird 的开源性,在国内有着众多厂商,不同厂商有时候也会设计自已品牌的系统字体包,所以即便是相同的代码,也可能在不同的安卓手机上呈现的效果也可能不相同,因此我们往往需要通过一些自定义控件来尽量保持效果的一致性!
系统自带 - 原始版(粗度固定,无扩展)
Android 为 TextView、EditText 提供了 textStyle 属性用于设置字体粗度
<TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:text="字体粗度"android:textStyle="bold" />
实现效果


关于 textStyle 属性值,主要提供了以下三种类型
- normal 默认正常字体
- bold 加粗字体
- italic 斜体
<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="MediumTextView"><attr name="mediumState" format="boolean" /></declare-styleable></resources>
自定义控件 - 基础版(扩展不足,基本够用)
首先在 attr/attrs 添加自定义属性
<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="MediumTextView"><attr name="mediumState" format="boolean" /></declare-styleable>
</resources>
实现效果

Tip:以下俩种方式均可正常使用,建议使用优化后的减少无效逻辑
优化前
package com.example.boldtextimport android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.support.v7.widget.AppCompatTextView
import android.util.AttributeSetclass MediumOldTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : AppCompatTextView(context, attrs, defStyleAttr) {private var mediumState: Boolean = falseinit {val array = context.obtainStyledAttributes(attrs, R.styleable.MediumTextView)mediumState = array.getBoolean(R.styleable.MediumTextView_mediumState, false)array.recycle()}override fun onDraw(canvas: Canvas?) {if (mediumState) {val strokeWidth = paint.strokeWidthval style = paint.stylepaint.strokeWidth = 0.6fpaint.style = Paint.Style.FILL_AND_STROKEsuper.onDraw(canvas)paint.strokeWidth = strokeWidthpaint.style = style} else {super.onDraw(canvas)}}fun setMediumState(mediumState: Boolean) {this.mediumState = mediumStaterequestLayout()}}
优化后
去除一些无用逻辑、代码
package com.example.boldtextimport android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.support.v7.widget.AppCompatTextView
import android.util.AttributeSetclass MediumTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : AppCompatTextView(context, attrs, defStyleAttr) {private var mediumState: Boolean = falseinit {val array = context.obtainStyledAttributes(attrs, R.styleable.MediumTextView)mediumState = array.getBoolean(R.styleable.MediumTextView_mediumState, false)array.recycle()}override fun onDraw(canvas: Canvas?) {if (mediumState) {//可通过设置该数值改变加粗字重paint.strokeWidth = 0.6fpaint.style = Paint.Style.FILL_AND_STROKE}super.onDraw(canvas)}fun setMediumText(mediumText: Boolean) {this.mediumState = mediumTextrequestLayout()
// postInvalidate()}}
使用方式
静态为 xml 设置,动态为代码设置
静态设置
<com.example.boldtext.MediumTextViewandroid:id="@+id/medium_view"android:layout_width="match_parent"android:layout_height="45dp"android:gravity="center"android:text="加粗字体"app:mediumState="true" />
动态设置
package com.example.boldtextimport android.support.v7.app.AppCompatActivity
import android.os.Bundleclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val mediumView = findViewById<MediumTextView>(R.id.medium_view)//设置加粗mediumView.setMediumState(true)}
}
自定义控件 - 进阶版(推荐:可自行扩展,定制化高)
实现效果

仅支持动态设置
Tip:假设别的组件也有字体加粗的需求,可以尝试继承该组件
创建 - 自定义组件
package com.example.boldtextimport android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.support.v7.widget.AppCompatTextView
import android.util.AttributeSetopen class TypefaceTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :AppCompatTextView(context, attrs, defStyleAttr) {private var mTypefaceScale: Float = 0.0fenum class TypefaceScale {MEDIUM, MEDIUM_SMALL, DEFAULT,}override fun onDraw(canvas: Canvas?) {if (mTypefaceScale == 0f) {return super.onDraw(canvas)}val strokeWidth = paint.strokeWidthval style = paint.stylepaint.strokeWidth = mTypefaceScalepaint.style = Paint.Style.FILL_AND_STROKEsuper.onDraw(canvas)paint.strokeWidth = strokeWidthpaint.style = style}fun setTypefaceScale(scale: TypefaceScale = TypefaceScale.DEFAULT) {mTypefaceScale = when (scale) {TypefaceScale.DEFAULT -> 0.0fTypefaceScale.MEDIUM_SMALL -> 0.6fTypefaceScale.MEDIUM -> 1.1f}postInvalidate()}}
使用方式
package com.example.boldtextimport android.support.v7.app.AppCompatActivity
import android.os.Bundleclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val typefaceView = findViewById<TypefaceTextView>(R.id.typeface_view)//设置加粗typefaceView.setTypefaceScale(TypefaceTextView.TypefaceScale.MEDIUM_SMALL)}
}
控件引入
<com.example.boldtext.TypefaceTextViewandroid:id="@+id/typeface_view"android:layout_width="match_parent"android:layout_height="45dp"android:gravity="center"android:text="TypefaceTextView 加粗字体" />
扩展:因为我们用的是 splitties 三方的一个布局组件,所以分享、记录一些扩展函数,逐步分析、学习
布局方式
add(lParams(), typefaceTextView {gravity = gravityEndtypefaceScale = TypefaceScale.MEDIUM_SMALLtextSize = 14ftextColor = "#333333".toColorInt()})
add函数 将子布局添加到对应ViewGroup中
import android.view.View
import android.view.ViewGroupinline fun <V : View> ViewGroup.add(lp: ViewGroup.LayoutParams, view: V): V = view.also { addView(it, lp) }
splitties - lParams 函数
inline fun LinearLayout.lParams(width: Int = wrapContent,height: Int = wrapContent,initParams: LinearLayout.LayoutParams.() -> Unit = {}
): LinearLayout.LayoutParams {contract { callsInPlace(initParams, InvocationKind.EXACTLY_ONCE) }return LinearLayout.LayoutParams(width, height).apply(initParams)
}inline fun LinearLayout.lParams(width: Int = wrapContent,height: Int = wrapContent,gravity: Int = -1,weight: Float = 0f,initParams: LinearLayout.LayoutParams.() -> Unit = {}
): LinearLayout.LayoutParams {contract { callsInPlace(initParams, InvocationKind.EXACTLY_ONCE) }return LinearLayout.LayoutParams(width, height).also {it.gravity = gravityit.weight = weight}.apply(initParams)
}
View - typefaceTextView 函数
// TypefaceTextView 防苹果系统的字体加粗------------------------------------------------------------------
inline fun Context.typefaceTextView(@IdRes id: Int = View.NO_ID,@StyleRes theme: Int = NO_THEME,initView: TypefaceTextView.() -> Unit = {}
): TypefaceTextView {return view(::TypefaceTextView, id, theme, initView)
}inline fun View.typefaceTextView(@IdRes id: Int = View.NO_ID,@StyleRes theme: Int = NO_THEME,initView: TypefaceTextView.() -> Unit = {}
): TypefaceTextView {return context.typefaceTextView(id, theme, initView)
}inline fun Ui.typefaceTextView(@IdRes id: Int = View.NO_ID,@StyleRes theme: Int = NO_THEME,initView: TypefaceTextView.() -> Unit = {}
): TypefaceTextView {return ctx.typefaceTextView(id, theme, initView)
}
// -------------------------------------------------------------------------------------------------------
typefaceTextView - typefaceScale 加粗类型函数
enum class TypefaceScale {
// MEDIUM,MEDIUM_SMALL,DEFAULT,
}var TypefaceTextView.typefaceScale: TypefaceScale@Deprecated(NO_GETTER, level = DeprecationLevel.HIDDEN) get() = noGetterset(value) {val scale = when (value) {
// TypefaceScale.MEDIUM -> TypefaceTextView.TypefaceScale.MEDIUMTypefaceScale.MEDIUM_SMALL -> TypefaceTextView.TypefaceScale.MEDIUM_SMALLTypefaceScale.DEFAULT -> TypefaceTextView.TypefaceScale.DEFAULT}setTypefaceScale(scale)}
支持动态、静态设置
为了方便直接在 xml 中使字体加粗,需要在控件上引入自定义属性,故需添加以下属性
<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="TypefaceTextView"><attr name="fontScale" format="enum"><enum name="normal" value="0" /><enum name="medium" value="1" /><enum name="bold" value="2" /></attr></declare-styleable>
</resources>
创建 - 自定义组件
package com.example.boldtextimport android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.support.v7.widget.AppCompatTextView
import android.util.AttributeSetclass TypefaceTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :AppCompatTextView(context, attrs, defStyleAttr) {private var mTypefaceScale: Float = 0.0finit {if (attrs != null) {val array = context.obtainStyledAttributes(attrs, R.styleable.TypefaceTextView)val typefaceScale = array.getInt(R.styleable.TypefaceTextView_fontScale, 0)mTypefaceScale = when (typefaceScale) {1 -> 0.6f2 -> 1.1felse -> 0.0f}array.recycle()}}enum class TypefaceScale {MEDIUM, DEFAULT, BOLD}override fun onDraw(canvas: Canvas?) {if (mTypefaceScale == 0f) {return super.onDraw(canvas)}val strokeWidth = paint.strokeWidthval style = paint.stylepaint.strokeWidth = mTypefaceScalepaint.style = Paint.Style.FILL_AND_STROKEsuper.onDraw(canvas)paint.strokeWidth = strokeWidthpaint.style = style}internal fun setTypefaceScale(scale: TypefaceScale = TypefaceScale.DEFAULT) {mTypefaceScale = when (scale) {TypefaceScale.DEFAULT -> 0.0fTypefaceScale.MEDIUM -> 0.6fTypefaceScale.BOLD -> 1.1f}invalidate()}}
静态设置
静态设置 fontScale 属性为枚举类型中的其一
<com.example.boldtext.TypefaceTextViewandroid:layout_width="match_parent"android:layout_height="45dp"android:gravity="center"app:fontScale="bold"android:text="TypefaceTextView 加粗字体" />
动态设置
package com.example.boldtextimport android.support.v7.app.AppCompatActivity
import android.os.Bundleclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val typefaceView = findViewById<TypefaceLTextView>(R.id.typeface_view)//设置加粗typefaceView.setTypefaceScale(TypefaceLTextView.TypefaceScale.MEDIUM)}
}
只能设置我们声明的枚举类型,如果项目需要扩展到更多粗度的话,可以自行增加!

相关文章:
Android进阶之路 - 字体加粗,定制化字体粗度
在客户端中不论是PC端,还是移动端主要价值之一就体现在用户交互方面,也就是用户体验了,接下来讲的是很常见的字体加粗问题 UI大找茬 深入浅出字体、字体库TextView文本渐变字体阴影、文字阴影字体加粗 - 定制化字体粗度 在开发中经常会遇到…...
ForkJoin框架的解析
Java 的 Fork/Join 框架是 Java 7 中引入的一种强大并发框架,旨在简化多线程编程,特别是对那些可以被递归地拆分成更小任务的任务。Fork/Join 框架的核心思想是将大任务拆分为多个小任务,并行运行这些小任务,然后将结果合并起来得…...
使用IDEA2019.1.4创建“hello world”java程序
使用IDEA创建“hello world”java程序分为4步: 创建工程->创建模块->创建库->创建类 1.创建工程 修改工程名称及地址 上步骤点击finish后,2019.1.4版本会自动弹出创建模块的窗口 2.创建模块 可以在上述窗口的基础上创建模块,也可…...
学习vue3 五,传送,缓存组件以及过渡和过渡列表
目录 Teleport传送组件 keep-alive缓存组件 transition动画组件 1. 过渡的类名 2. 自定义过渡class名 3. transition的生命周期 4.appear transition-group 1. 过渡列表 2. 列表的移动过渡 3. 状态过渡 Teleport传送组件 Teleport Vue 3.0新特性之一。 Teleport 是一…...
MyBatis快速学习
目录 前言 MyBatis的具体使用 一些小工具:MyBatisX 常见问题: 1.表中字段名和实体属性名不一致 2.按条件查询(单条件)时的,查询条件怎么编写 3.按条件查询(多条件) 4.多条件查询时&…...
24.8.3数据结构|双向循环链表、静态链表
双向循环链表 节点类型与双链表的节点类型完全相同双向循环链表的操作也与双链表的操作基本一致。 例题 将自然数一到N按由小到大的顺序沿顺时针方向围成一个圈,然后以一为起点先沿顺时针方向数到第N个数将其划去,再沿逆时针方向数到第K个数将其滑去&a…...
C语言典型例题28
《C程序设计教程(第四版)——谭浩强》 习题2.5 输入一个华氏温度,要求输出摄氏温度。公式为C5/9(F-32),要求输出要有文字说明,取两位小数 数学知识: (1)华氏温度与摄氏温度&#x…...
PHP企业培训考试系统小程序源码
🚀企业培训考试系统,赋能员工成长新引擎📚 🌱 开篇:解锁企业培训新篇章 在快速变化的商业环境中,员工的能力提升是企业持续发展的关键。🚀 传统的培训方式已难以满足现代企业的需求࿰…...
进程状态(三)----- linux 中具体的进程状态(下)
目录 前言1. T && t 状态2. X 与 Z 状态3. 孤儿进程 前言 继上一篇文章 进程状态(二)----- linux 中具体的进程状态(上) 介绍了 linux 系统中具体的 R、S、D 状态,而这篇文章继续介绍 linux 系统中剩下的三种…...
关系型数据库(RDBMS,Relational Database Management System)
关系型数据库(RDBMS,Relational Database Management System)是一种结构化数据存储系统,它使用表(Tables)、行(Rows)和列(Columns)的结构来组织和管理数据。关…...
使用RK Docker环境编译RK SDK
文章目录 前言Docker介绍实验环境获取RK Docker镜像加载RK Docker镜像使用RK Docker环境编译SDK其它 前言 作为一名嵌入式Linux的学习者,目前编译各种平台,用的都是同一个编译机(Ubuntu虚拟机)。之前一直在折腾全志,所…...
免费【2024】springboot 付费自习室管理系统的设计与实现
博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…...
【学习方法】高效学习因素 ② ( 学习动机 | 内在学习动机 | 外在学习动机 | 外在学习动机的调整方向 | 保护学习兴趣 | 高考竞争分析 )
文章目录 一、高效学习的其它因素 - 学习动机1、学习动机2、内在学习动机3、外在学习动机4、外在学习动机的问题所在5、外在学习动机的调整方向6、保护学习兴趣7、高考竞争分析 上一篇博客 【学习方法】高效学习因素 ① ( 开始学习 | 高效学习因素五大因素 | 高效学习公式 - 学…...
【学习笔记】A2X通信的协议(四)- A2X PC5通信(二)
目录 6.1.2.4 A2X PC5单播链接释放程序 6.1.2.4.1 概述 6.1.2.4.2 发起UE启动A2X PC5单播链接释放程序 6.1.2.4.3 目标UE接受的A2X PC5单播链接释放程序 6.1.2.4.4 发起UE完成的A2X PC5单播链接释放程序 6.1.2.4.5 异常情况 6.1.2.4.5.1 发起UE的异常情况 6.1.2.5 A2X …...
注意!!可能这是《网络管理员》旧教程最后一次考试,赶紧学起来
网络管理员是软考初级资格热门科目之一。近日在国家版本数据中心,小编查到网络管理员官方教程已经有2024最新版出来了,现在这一版教程说实话有些内容已经过时了,尤其新版教材也已经出现,小编推测明年大概率依据新版考试大纲出题&a…...
array postgre gsql 剔除
进行某种过滤或比较操作,判断不匹配的,数组 array 中列出的所有字符串 and a.Repunittree not like all (array[‘%0001003549950003%’,‘%000100460041%’,‘%000100460047%’,‘%000105880001%’ ,‘%000100020007%’,‘%000105830009%’,‘%0001058…...
【Matlab】零阶保持法:连续状态空间方程(含噪声,非线性)离散化处理方法
常用的离散化方法:零阶保持器(zero-order hold,ZOH)、欧拉法(Euler)、一阶保持器(First-order hold,FOH)。最常用的是前两种。 0.零阶保持器(ZOH)…...
web自动化6-pytest⑦一些基本情况
命名规则 1)import pytest 测试文件名要以test_ 开头或 _test结尾 2)类名需要以Test开头(T),不能带有init方法 3)函数名以test_开头(t) 符合规则框架才能找到用例,一条用例代表一条函…...
apache 漏洞
影响版本 Apache HTTP Server 2.4.49 某些Apache HTTPd 2.4.50也存在此漏洞 环境搭建 docker pull blueteamsteve/cve-2021-41773:no-cgid 漏洞复现 http://1.15.136.212:8080 1.使⽤poc curl http://1.15.136.212:8080/cgi-bin/.%2e/.%2e/.%2e/.%2e/etc/passwd...
简单的docker学习 第11章 镜像中心
第11章 镜像中心 Docker Hub 与阿里云都是 Docker 的公网镜像中心,用户可以将自己的镜像 push 到公网镜像中心中自己的镜像仓库,并可将仓库设置为私有库,使他人无法看到,更无法 pull,以保证镜像的安全性。不过&#x…...
pgloader:从数据孤岛到PostgreSQL的高效迁移引擎
pgloader:从数据孤岛到PostgreSQL的高效迁移引擎 【免费下载链接】pgloader Migrate to PostgreSQL in a single command! 项目地址: https://gitcode.com/gh_mirrors/pg/pgloader 一、工具定位与核心优势:为什么选择pgloader? 1.1 数…...
GLM-4-9B-Chat-1M多场景:法律、医疗、教育、电商四大行业落地实践汇总
GLM-4-9B-Chat-1M多场景:法律、医疗、教育、电商四大行业落地实践汇总 1. 引言:当大模型遇上超长文本 想象一下,你是一位律师,需要分析一份长达500页的合同文档;或者是一位医生,要快速理解病人的完整病历…...
Filament Shield 策略生成器:自动化权限策略开发完全指南
Filament Shield 策略生成器:自动化权限策略开发完全指南 【免费下载链接】filament-shield The easiest and most intuitive way to add access management to your Filament Panel; Resources, Pages & Widgets through spatie/laravel-permission 项目地址…...
WebSocket 命令行神器 wscat:5分钟快速上手 WebSocket 调试
WebSocket 命令行神器 wscat:5分钟快速上手 WebSocket 调试 【免费下载链接】wscat WebSocket cat 项目地址: https://gitcode.com/gh_mirrors/ws/wscat wscat 是一款轻量级的 WebSocket 命令行工具,能帮助开发者快速测试和调试 WebSocket 连接&a…...
终极阴阳师自动化指南:如何用OAS脚本每天节省2小时
终极阴阳师自动化指南:如何用OAS脚本每天节省2小时 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 还在为阴阳师无尽的日常任务感到疲惫吗?每天重复的御魂…...
华硕笔记本性能调校新选择:G-Helper轻量控制工具全解析
华硕笔记本性能调校新选择:G-Helper轻量控制工具全解析 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, S…...
整理了这份大厂Java面试 / 学习指南,共计1500+ 题全面解析
程序员一步入中年,不知不觉便会被铺天盖地的“危机感”上身,曾经的那个少年已经不在,时间就是这样公平。就算你能发明 Java 语言,随着时间的推移,你注定还是要成为慢慢变蔫的茄子,缓缓变黑的葡萄。 看着金…...
STK 9.2.2 实战:手把手教你用TLE文件导入中国空间站轨道数据
STK 9.2.2 实战:手把手教你用TLE文件导入中国空间站轨道数据 航天仿真领域的新手们常常被一个问题困扰:如何在自己的STK项目中快速添加真实卫星轨道数据?本文将带你从零开始,一步步完成中国空间站轨道数据的导入,避开那…...
新手入门:5分钟搞懂雷达中的Dwell Time和Hits per Scan(附计算公式)
雷达系统核心参数解析:从Dwell Time到Hits per Scan的实战指南 雷达技术作为现代探测系统的基石,其性能优劣往往取决于几个关键参数的精确配置。对于刚接触雷达领域的技术人员来说,理解这些参数的实际意义和相互关系,就像掌握了一…...
YOLO26改进 - 注意力机制 | Polarized Self-Attention 极化自注意力:高分辨率保持机制优化细节表征,助力小目标检测
前言 本文介绍了极化自注意力(PSA)模块及其在YOLO26中的结合应用。PSA模块旨在解决细粒度计算机视觉任务中的像素级回归问题,其融合了极化过滤和增强两个关键设计。极化过滤在通道和空间维度保持高分辨率,减少信息损失;增强采用细粒度回归输出分布的非线性函数。我们将Po…...
