将图像顶部与 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 顶部对齐的主要内容,如果未能解决你的问题,请参考以下文章