【问题标题】:How to set drawable in Top-Left in a textview?如何在文本视图的左上角设置drawable?
【发布时间】:2019-11-30 10:43:36
【问题描述】:
<TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawablePadding="@dimen/padding_small_6"
        android:includeFontPadding="false"
        android:text="@string/forgot_password_hint"
        android:drawableStart="@drawable/ic_edit"
        android:textSize="@dimen/text_size_medium_14"/>

这是我的文本视图。我想在这个textview的左边设置drawable。但问题是,如果文本是多行的,那么 drawable 在文本视图中会出现 center-vertical。

是否有任何选项可以在 textview 的左上角设置可绘制对象?

【问题讨论】:

    标签: android android-layout textview


    【解决方案1】:

    不,它们没有任何直接选项可以在 textview 的左上角设置可绘制对象。

    但是您可以创建一些自定义设计来实现这一点。用下面的代码替换你的TextView

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <ImageView
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:src="@drawable/ic_edit" />
    
            <TextView
                android:id="@+id/text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:includeFontPadding="false"
                android:text="@string/forgot_password_hint"
                android:textSize="@dimen/text_size_medium_14"/>
        </LinearLayout>
    

    【讨论】:

    • 我想到了这个,但是这种方法需要大量的可见性处理。
    【解决方案2】:

    通过扩展可绘制类并用于可绘制类来制作自定义可绘制类。例如:

    public class TopLeftGravityDrawable extends BitmapDrawable {
       private final Drawable mDrawable;
    
       public TopLeftGravityDrawable(Drawable drawable) {
           mDrawable = drawable;
       }
    
       @Override
       public int getIntrinsicWidth() {
           return mDrawable.getIntrinsicWidth();
       }
    
       @Override
       public int getIntrinsicHeight() {
           return mDrawable.getIntrinsicHeight();
       }
    
       @Override
       public void draw(Canvas canvas) {
           int halfCanvas= canvas.getHeight() / 2;
           int halfDrawable = mDrawable.getIntrinsicHeight() / 2;
    
           // align to top
           canvas.save();
           canvas.translate(0, -halfCanvas + halfDrawable);
           mDrawable.draw(canvas);
           canvas.restore();
       }
    }
    

    用法:

           Drawable drawable = getResources().getDrawable(R.drawable.ic_customer);
    
           TopGravityDrawable gravityDrawable = new TopGravityDrawable(drawable);
    
           drawable.setBounds(0, 6, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
           gravityDrawable.setBounds(0, 6, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
           textview.setCompoundDrawables(gravityDrawable, null, null, null);
    

    【讨论】:

      【解决方案3】:

      如果编程方法合适,您可以扩展 Drawable,使其占据可用的全部高度并在顶部绘制。

      如果您想要一个仅使用界面构建器的解决方案,您应该将 TextView 包装在水平 LinearLayout 中,添加一个 ImageView 并将 ImageViews 的重力设置为 TOP。

      【讨论】:

      • 我正在尝试仅采用程序化方法。 Android 没有提供任何 XML 方法来实现这一点。
      【解决方案4】:

      在 xml 文件中试试这个

      将 android:drawableStart 更改为 android:drawableLeft

      <TextView
              android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:drawablePadding="@dimen/padding_small_6"
              android:includeFontPadding="false"
              android:text="@string/forgot_password_hint"
              android:drawableLeft="@drawable/ic_edit"
              android:textSize="@dimen/text_size_medium_14"/>
      

      【讨论】:

      • 这在多行文本的情况下不起作用。 Drawable 始终显示为 textview 的“中心垂直”。
      【解决方案5】:

      使用android:paddingBottom="10dp"

      【讨论】:

      • 从底部添加内边距也会为文本添加内边距。
      【解决方案6】:

      这解决了我的问题:

      class MyTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null
          ) : AppCompatTextView(context, style) {
              private val leftDrawable = ContextCompat.getDrawable(context, R.drawable.checkmark)
          
              override fun onDraw(canvas: Canvas?) {
                  super.onDraw(canvas)
                  setBulletPoint(compoundDrawables[0], canvas)
              }
          
          private fun setBulletPoint(drawableLeft: Drawable?, canvas: Canvas?) {
              if (!TextUtils.isEmpty(text)) {
                  leftDrawable?.let { drlft ->
                      if (lineCount == 1) {
                          setCompoundDrawablesWithIntrinsicBounds(drlft, null, null, null)
                      } else {
                          val buttonWidth = drlft.intrinsicWidth
                          val buttonHeight = drlft.intrinsicHeight
                          val topSpace = abs(buttonHeight - lineHeight) / 2
                 
                          drlft.setBounds(0, topSpace, buttonWidth, topSpace + buttonHeight)
                          canvas?.apply {
                              save()
                              drlft.draw(canvas)
                              restore()
                          }
                      }
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案7】:

        类似于@Avinash Kumar Singh 的解决方案。如果您有一个小图像,它将高于第一行文本。

        在这种情况下,您应该以第一行为中心。

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tool="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingTop="8dp">
        
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:drawableStartCompat="@drawable/dot"
                tool:drawableStart="@drawable/dot" />
        
            <TextView
                android:id="@+id/title"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                tool:text="This is my textview. I want to set the drawable on left of this textview" />
        
        </LinearLayout>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-01-21
          • 1970-01-01
          • 2015-09-22
          • 1970-01-01
          • 2016-08-28
          • 2023-03-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多