将图像顶部对齐到TextView顶部

时间:2012-04-22 10:58:29

标签: android android-layout textview drawable vertical-alignment

我想创建一个布局,将图像的顶部与TextView的顶部对齐,如下所示:

---------  Text text text text text text text
| Image |  text text text text text text text
---------  text text text text text text text
           text text text text text text text
           text text text text text.

我尝试通过将android:drawableLeft设置为我的图片来实现此目的,但这会使图像垂直居中:

           Text text text text text text text
---------  text text text text text text text
| Image |  text text text text text text text
---------  text text text text text text text
           text text text text text.

仅使用TextView是否可行,还是需要创建包含TextView和ImageView的RelativeLayout?

以下是TextView的XML布局,它提供了错误的布局:

<TextView
    android:gravity="top"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:drawableLeft="@drawable/image"
    android:drawablePadding="8dp"
    android:text="@string/text" />

android:gravity="top"属性似乎只影响文本,而不影响drawable。

6 个答案:

答案 0 :(得分:28)

您可以通过创建包装Drawable的自定义Drawable将Compound-Drawable对齐到顶部(或底部),然后通过覆盖方法onDraw(Canvas)来操纵自定义Drawable的绘图。

以下示例是最简单的示例。这会将图像与顶部对齐,但您也可以通过在onDraw(Canvas) - 方法中实现所需的逻辑使其与TextView的底部,左侧或右侧对齐。您可能还希望在onDraw(Canvas)中建立边距,以使您的设计实现像素完美。

样本用法:

GravityCompoundDrawable gravityDrawable = new GravityCompoundDrawable(innerDrawable);
// NOTE: next 2 lines are important!
innerDrawable.setBounds(0, 0, innerDrawable.getIntrinsicWidth(), innerDrawable.getIntrinsicHeight());
gravityDrawable.setBounds(0, 0, innerDrawable.getIntrinsicWidth(), innerDrawable.getIntrinsicHeight());
mTextView.setCompoundDrawables(gravityDrawable, null, null, null);

示例代码:

public class GravityCompoundDrawable extends Drawable {

    // inner Drawable
    private final Drawable mDrawable;

    public GravityCompoundDrawable(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();
    }
}

答案 1 :(得分:1)

尝试使用RelativeLayout ......

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/imageView1"
        android:text="@string/text" />

</RelativeLayout>

答案 2 :(得分:1)

我认为,有比3个视图更容易,更快捷的方式。您需要为图标准备适当的9patch,然后使用FrameLayout。甚至可以只使用与背景相同的 EditText / TextView。更多详细信息在this answer中进行了描述。

答案 3 :(得分:0)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/imageView1"
        android:text="@string/text" />

</RelativeLayout>

这样做。

答案 4 :(得分:0)

使用layout_alignTop。有了它,您可以将视图的顶部与另一个视图的顶部对齐

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/text" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@id/textView1"
        android:layout_toLeftOf="@id/textView1"
        android:src="@drawable/ic_launcher" />    

</RelativeLayout>

答案 5 :(得分:0)

这对我有用:

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()
                    }
                }
            }
        }
    }
}
相关问题