【问题标题】:How to position icon position in materialbutton如何在materialbutton中定位图标位置
【发布时间】:2019-03-26 22:45:59
【问题描述】:

我正在使用支持库中的 Materialbutton。我希望图标位于文本的右侧?我似乎找不到如何做到这一点。 任何帮助表示赞赏

【问题讨论】:

  • 我更愿意让它根据locale自动选择图标位置

标签: android android-button material-components-android material-components


【解决方案1】:

尝试在开始和结束时添加填充。你应该能够用它来定位图标。例如:

<androidx.appcompat.widget.AppCompatButton
                        android:id="@+id/fai_btn_dislike"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="16dp"
                        android:paddingLeft="16dp"
                        android:paddingRight="16dp"
                        android:layout_weight="1"
                        android:background="@drawable/btn_rounded"
                        android:drawableStart="@drawable/ic_thumb_down"
                        android:text="@string/fai_dislike"
                        app:icon="@drawable/ic_thumb_down" />

【讨论】:

    【解决方案2】:

    如果你正在寻找只有一个图标的材质按钮,只需复制这个类并使用它:

    /**
     * Created by osapps on 1/20/21.
     *
     * This is a simple class of a material button with just an icon. You can set whatever you want in the xml to use this, but just make sure to also
     * the button's insetTop, insetBottom, insetLeft and insetRight to 0.
     */
    class MaterialIconButton : MaterialButton {
    
        // indications
        private var absPropsSet = false
    
        constructor(context: Context) : super(context) {
            commonInit()
        }
    
        constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
            commonInit()
        }
    
        constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
            context,
            attrs,
            defStyleAttr
        ) {
            commonInit()
        }
    
        private fun commonInit() {
            setBackgroundColor(Color.TRANSPARENT)
            strokeWidth = 0
            stateListAnimator = null
            iconTintMode = PorterDuff.Mode.MULTIPLY
            iconGravity = ICON_GRAVITY_TEXT_START
            iconPadding = 0
        }
    
        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
            if(!absPropsSet) {
                iconSize = measuredWidth - paddingStart
            }
        }
    
        /**
         * Will set absolute properties for the button. Call this function to make the button look exactly as you want.
         * NOTICE: don't forget to set, in the xml, the button's insetTop, insetBottom, insetLeft and insetRight to 0.
         */
        fun setAbsProps(iconSize: Int, @DimenRes paddingRes: Int? = null) {
            absPropsSet = true
            var padding = 0
            paddingRes?.apply { padding = resources.getDimensionPixelSize(paddingRes) }
            setPadding(0, 0, 0, 0)
            this.iconSize = iconSize
            layoutParams.width = iconSize + padding
            layoutParams.height = iconSize + padding
        }
    
    }
    

    使用示例:

    <com.osfunapps.remoteforsamsung.views.MaterialIconButton
                android:id="@+id/no_ads_btn"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_margin="12dp"
    
                android:insetLeft="0dp"
                android:insetTop="0dp"
                android:insetRight="0dp"
                android:insetBottom="0dp"
                android:padding="12dp"
    
                android:onClick="onNoAdsClick"
                app:icon="@drawable/ic_crown"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintWidth_percent="0.15"
                app:layout_constraintDimensionRatio="1:1"
                app:rippleColor="#F8CE36"
                />
    

    【讨论】:

      【解决方案3】:

      您可以使用 app:iconGravity 属性。
      使用app:iconGravity="end" 值。

      【讨论】:

        【解决方案4】:

        实现这一点的唯一布局方法是:

        如果您使用的是支持库

        implementation 'com.android.support:design:28.0.0'
        

        你可以试试

        <android.support.v7.widget.AppCompatButton
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableRight="@android:drawable/ic_menu_camera"
            android:text="Camera" />
        

        如果您使用的是较新的材质 ui 库

        implementation 'com.google.android.material:material:1.0.0'
        

        你可以试试

        <androidx.appcompat.widget.AppCompatButton
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableRight="@android:drawable/ic_menu_camera"
            android:text="Camera" />
        

        【讨论】:

          【解决方案5】:

          MaterialButton 没有公共 API 允许您将图标放在文本的右侧。这个private方法控制图标的绘制:

          private void updateIcon() {
              if (this.icon != null) {
                  this.icon = this.icon.mutate();
                  DrawableCompat.setTintList(this.icon, this.iconTint);
                  if (this.iconTintMode != null) {
                      DrawableCompat.setTintMode(this.icon, this.iconTintMode);
                  }
          
                  int width = this.iconSize != 0 ? this.iconSize : this.icon.getIntrinsicWidth();
                  int height = this.iconSize != 0 ? this.iconSize : this.icon.getIntrinsicHeight();
                  this.icon.setBounds(this.iconLeft, 0, this.iconLeft + width, height);
              }
          
              TextViewCompat.setCompoundDrawablesRelative(this, this.icon, (Drawable)null, (Drawable)null, (Drawable)null);
          }
          

          不过,如果您不使用 app:iconGravity,您可以通过在布局膨胀后手动更改按钮的复合可绘制对象来解决这个问题:

          Button b = findViewById(R.id.button);
          Drawable d = TextViewCompat.getCompoundDrawablesRelative(b)[0]; // the start drawable
          TextViewCompat.setCompoundDrawablesRelative(b, null, null, d, null); // move it to the end
          

          【讨论】:

          • 谢谢你的建议。太好了,谢谢
          • 截至1.1.0-alpha06(2019 年 5 月)发布时,他们确实引入了这种方法,但重力选项有限(意味着顶部或底部都没有)。尝试使用TextViewCompat.setCompoundDrawablesRelative 将触发requestLayout,在某些时候会调用MaterialButton#updateIconPosition,而后者又会调用updateIcon。此方法的源代码自您发布以来已更改,现在显示 TOP 或 BOTTOM 重力被忽略。所以,除了回到1.1.0-alpha05(从2019年3月开始),我相信还有其他方法。假设我正确吗?
          【解决方案6】:

          如果您使用app:icon= 并且它位于左侧,则当您制作RTL 布局时,它也会显示来自RTL 的图标。

          LTR:

          将区域设置更改为RTL

          这似乎是正常行为,它会自动完成这项工作。 但是,您最好添加:

          implementation 'com.google.android.material:material:1.0.0'
          

          在您的应用程序中build.gradle 依赖项,以便使用最新的MaterialButton,这更适合此目的。

          我还从com.google.android.material.button.MaterialButton 阅读了the documentation 关于MaterialButton 的内容,其中提到:

          将图标添加到该按钮的start或该按钮的中心,使用 app:iconapp:iconPaddingapp:iconTintapp:iconTintModeapp:iconGravity 属性。

          但不幸的是,没有任何属性可以解决问题。除了具有start - textStartapp:iconGravity 属性。

          解决方案:

          只需添加:

          android:layoutDirection="rtl"
          

          致您的MaterialButton

          <com.google.android.material.button.MaterialButton
              android:id="@+id/guestLogin"
              style="@style/Widget.MaterialComponents.Button"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_below="@+id/relativeLayout"
              android:layout_centerHorizontal="true"
              android:layout_marginTop="10dp"
              android:layoutDirection="rtl"
              android:text="@string/login_as_guest"
              android:textColor="@color/whiteColor"
              app:icon="@drawable/ic_keyboard_arrow_left_white_24dp" />
          


          但是,与此同时,我也 created a pull request 的文档中存在问题。希望他们能改正错字。

          将图标添加到此按钮的此按钮的开头或中心

          顺便说一句,如果他们在app:iconGravity="" 属性中添加end 会更好。

          【讨论】:

          • 感谢您的回答,但这真的很糟糕。您正在强制使用某种布局,这会扼杀应用程序的语言切换功能。另外,必须将图像设计为翻转以匹配此。这绝对是一个有趣的想法,但我会远离这个
          猜你喜欢
          • 2013-12-18
          • 2019-01-09
          • 1970-01-01
          • 2021-07-26
          • 1970-01-01
          • 1970-01-01
          • 2016-01-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多