如何在文本视图的左上角设置可绘制对象?

How to set drawable in Top-Left in a textview?

<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"/>

这是我的文本视图。我想在此文本视图的左侧设置可绘制对象。但问题是,如果文本是多行的,那么 drawable 会在文本视图中显示为居中垂直。

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

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

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

在 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"/>

No, their is no any direct option to set drawable on Top-Left of the 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>

使用android:paddingBottom="10dp"

通过扩展可绘制对象 class 制作自定义可绘制对象 class 并用于可绘制对象。例如:

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);

这已经解决了我的问题:

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

类似于@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>