美文网首页
MaterialButton 的宽度、高度问题

MaterialButton 的宽度、高度问题

作者: 小强开学前 | 来源:发表于2022-07-09 18:34 被阅读0次

    最近写一个自定义控件,发现 MaterialButton 相关的问题颇多,在此记录

    1. MaterialButton 文字与 Icon 的BUG

    • MaterialButton width match_parent, 设置 Gravity 为 START,IconGravity 为 textEnd

    结果按钮与文字之间有一定距离,后来在GitHub上发现这是一个BUG,升级版本修复

    • MaterialButton width wrap_content,IconGravity 为 textEnd

    结果 Icon跑到文字前边,后来发现只能设置 IconGravity 为 end

    2. 如何让 MaterialButton 的大小变小,或者说看起来像TextView

    结合使用minWidth/minHeight,minimalWidth/minimalHeight,insetTop/...,leftPadding/...

    3. OutlinedButton 宽度问题

    设置三个View,分别为 MaterialButton、TextView、View
    统一设置背景、文字颜色、文字大小,比较各长度
    View 是通过测量出数字然后设置宽度

    文字 打印
    My Application 295,292, 292
    My ApplicationApplication 519,514, 514

    另外一台手机居然三个数字都不同

    发现跟背景、圆角都没关系,代码里设置 background 为 null 也不行
    跟上面第二点的最小宽度也没关系
    甚至 IconSize 和 IconPadding 我也尝试了,没有关系

    然后看显示效果,发现 Button 的文字粗一些,难道跟 fontWeight 有关系?

    显示效果

    确实是,修改 TypeFace 之后宽度一样了

    继续研究,发现
    MaterialButton 默认的是TypeFace@20046,style为0,weight为500
    MaterialTextView 默认的是TypeFace@20087,style为0,weight为400

    TextView使用的是默认字体,这个每个手机都可以自己设置,我这里是TypefaceCompat.create(it.context, Typeface.SANS_SERIF, Typeface.NORMAL)

    而 MaterialButton 是 style 为Widget.MaterialComponents.Button下的<item name="android:textAppearance">?attr/textAppearanceButton</item>指定的

    继续找,发现textAppearance是在style为Widget.Material.Button下的<item name="textAppearance">?attr/textAppearanceButton</item>指定的。

    也就是说,取决于我们项目中使用的主题里面的这个属性
    而我的测试Demo是Theme.MaterialComponents.DayNight.DarkActionBar,继续看一下。

    Base.V14.Theme.MaterialComponents.Light.Bridge => <item name="textAppearanceButton">@style/TextAppearance.MaterialComponents.Button</item>

    最终找到

    <style name="TextAppearance.MaterialComponents.Button" parent="Base.TextAppearance.MaterialComponents.Button">
    <!-- Roboto Medium was added in this api level -->
    <item name="fontFamily">sans-serif-medium</item>
    <item name="android:fontFamily">sans-serif-medium</item>
    <item name="android:textStyle">normal</item>
    

    结论:

    Button、TextView等即使去除所有影响布局的因素仍然可能大小不同,本质是字体不同,MaterialButton 默认使用 FontWeight 为500的字体,而 FontWeight 在API28才被添加。

    TextPaint 也有个 TypeFace,所以很可能出现三个不一样的值。

    测试代码

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <com.google.android.material.button.MaterialButton
            android:id="@+id/btn"
            style="@style/Widget.MaterialComponents.Button.OutlinedButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:insetTop="0dp"
            android:insetBottom="0dp"
            android:letterSpacing="0"
            android:minWidth="0dp"
            android:minHeight="0dp"
            android:padding="0dp"
            android:text="@string/app_name"
            android:textAllCaps="false"
            android:textColor="@android:color/holo_red_dark"
            android:textSize="16dp"
            app:backgroundTint="@color/black"
            app:cornerRadius="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:strokeWidth="0dp" />
    
        <TextView
            android:id="@+id/btn2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:background="@color/black"
            android:text="@string/app_name"
            android:textColor="@android:color/holo_red_dark"
            android:textSize="16dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn" />
    
        <View
            android:id="@+id/test"
            android:layout_width="10dp"
            android:layout_height="10dp"
            android:layout_marginTop="2dp"
            android:background="@color/black"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn2" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
    class MainActivity : AppCompatActivity() {
    
        private lateinit var mBinding: ActivityMainBinding
    
        private var itemCount = 0
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            mBinding = ActivityMainBinding.inflate(layoutInflater)
            setContentView(mBinding.root)
    
    
            val paint = TextPaint(Paint.ANTI_ALIAS_FLAG)
            paint.textSize = 16.dp
    
            mBinding.test.doOnPreDraw {
                val w = paint.measureText(it.context.getString(R.string.app_name)).toInt()
                it.layoutParams.width = w
                Log.d("lq","${mBinding.btn.measuredWidth},${mBinding.btn2.measuredWidth}, $w")
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:MaterialButton 的宽度、高度问题

          本文链接:https://www.haomeiwen.com/subject/vbcibrtx.html