如何在TextView中将Drawable设置为左上角?

5
<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会出现在TextView的垂直中心。
有没有选项可以将Drawable设置为在TextView的左上方?
7个回答

3

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

enter image description here

在这种情况下,您应该将图像置于第一行的中心位置。

<?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>

enter image description here


2
没有直接设置drawable在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>

我想到了这个方法,但这种方法需要大量处理可见性。 - Ashish John

1
通过扩展drawable类来创建自定义的drawable类,并用于drawable。例如:
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);

1

这解决了我的问题:

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()
                    }
                }
            }
        }
    }
}

如果你想保留可绘制的填充,你应该修改你的代码,像这样: canvas.apply { save() it.draw(canvas) setPadding(buttonWidth + compoundDrawablePadding, 0, 0, 0) restore() } 无论如何,这对我很有帮助。 - undefined

0
如果采用编程方法,您可以扩展Drawable,使其占用可用的全部高度并在顶部绘制。
如果您想使用界面构建器来解决问题,只需将TextView包装在水平LinearLayout中,添加一个ImageView,并将ImageView的gravity设置为TOP即可。

我只想采用编程方法来解决这个问题。Android没有提供任何XML方法来实现这一点。 - Ashish John

-1

使用 android:paddingBottom="10dp"


2
从底部添加填充会使文本也添加填充。 - Ashish John

-1
尝试在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的“垂直居中”位置。 - Ashish John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接