将图像顶部与 TextView 顶部对齐

Posted

技术标签:

【中文标题】将图像顶部与 TextView 顶部对齐【英文标题】:Align top of image to top of TextView 【发布时间】:2012-05-03 06:51:43 【问题描述】:

我想创建一个布局,将图像的顶部与 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_
    android:layout_
    android:drawableLeft="@drawable/image"
    android:drawablePadding="8dp"
    android:text="@string/text" />

android:gravity="top" 属性似乎只影响文本,而不影响可绘制对象。

【问题讨论】:

我认为你需要使用 relativeLayout... 无论你需要在顶部还是左侧 正如@amp 所说,使用相对布局最好.. @Claes 你找到答案了吗?我也面临类似的问题 @user3265443 使用一个自定义 Drawable 来包装你的 Drawable。有关示例代码,请参阅我的答案:***.com/a/28906636/710990。 【参考方案1】:

您可以通过创建一个包裹您的 Drawable 的自定义 Drawable 来将复合 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();
    

【讨论】:

很好的解决方案。这必须是公认的答案。 如何使用它来对齐文本和左侧可绘制到 textview 的左侧 我必须将gravityDrawable的下界设置为0:gravityCompoundDrawable.setBounds(0, 0, originalCompoundDrawable.getIntrinsicWidth(), 0); 我不明白这是怎么被接受的答案。除非您还覆盖 getOpacity()、setAlpha(...) 和 setColorFilter(...),否则它不会编译。这 3 种方法的功能是什么? @Tharkius 答案中省略了这些方法,因为它们与对齐问题无关,但是您是对的,当您创建自定义 Drawable 时需要实现它们,就像我们一样在这里做。在这种特定情况下,您可能会为每个方法 getOpacity()、setAlpha() 和 setColorFilter() 调用 mDrawable 字段上的相应方法。所以在getOpacity()中你会返回mDrawable.getOpacity(),在setAlpha()中你会调用mDrawable.setAlpha(..)等等。这些方法的含义你可以在Drawable的文档中找到。【参考方案2】:

尝试使用RelativeLayout......

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

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

    <TextView
        android:layout_
        android:layout_
        android:layout_toRightOf="@id/imageView1"
        android:text="@string/text" />

</RelativeLayout>

【讨论】:

CompoundDrawable 的要点是尽量减少视图层次结构中的视图数量。这个解决方案没有回答这个问题,即使它在视觉上看起来是一样的。【参考方案3】:

我认为,有一种比 3 个视图更简单、更快捷的方法。您需要为图标准备适当的 9patch,然后使用 FrameLayout。甚至可能只有 single EditText / TextView 使用相同的可绘制对象作为背景。更多细节在this answer中描述。

【讨论】:

【参考方案4】:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_ >

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

    <TextView
        android:layout_
        android:layout_
        android:layout_toRightOf="@+id/imageView1"
        android:text="@string/text" />

</RelativeLayout>

这样就可以了。

【讨论】:

【参考方案5】:

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

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

    <TextView
        android:id="@+id/textView1"
        android:layout_
        android:layout_
        android:text="@string/text" />

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

</RelativeLayout>

【讨论】:

【参考方案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()
                    
                
            
        
    

【讨论】:

以上是关于将图像顶部与 TextView 顶部对齐的主要内容,如果未能解决你的问题,请参考以下文章

Android TextView 中真正的顶部对齐文本

将 UIImageView 与 contentMode AspectFill 和顶部对齐

如何将此 Wordpress 图片标题与图片顶部对齐?

将两个元素与表格单元格的顶部和底部对齐

如何在屏幕的中心顶部对齐图像行

带有图像和文本的 HTML 标头 - 将文本与底部对齐?