将 ImageView 与 EditText 水平对齐

发布于 2025-01-07 16:49:24 字数 1969 浏览 4 评论 0原文

我正在努力寻找一种在 Android 上EditTextImageView 正确 对齐的方法。我不断得到这个结果:

在此处输入图像描述

XML 部分非常简单:

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:scaleType="centerInside"
        android:src="@drawable/android"
        android:visibility="gone" />

    <EditText
        android:id="@+id/edittext"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:singleLine="true" />

</LinearLayout>

我也尝试了许多建议下面,包括 PravinCG 的(具有alignTop/alignBottom 的RelativeLayout):

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/edittext"
        android:layout_alignTop="@+id/edittext"
        android:scaleType="centerInside"
        android:src="@drawable/android"
        android:visibility="visible" />

    <EditText
        android:id="@+id/edittext"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/image"
        android:hint="@string/username"
        android:singleLine="true" />

</RelativeLayout>

但结果是完全相同的。

我尝试过使用 EditText 的背景填充、固有高度,但无济于事。

EditText 的背景绘制在 Android 版本/ROM 之间有所不同,我想支持它们。

如何在任何 Android 版本(和样式)上实现像素完美对齐?

I'm trying hard to find a way of aligning an EditText and an ImageView properly on Android. I keep getting this result:

enter image description here

The XML part is quite simple:

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:scaleType="centerInside"
        android:src="@drawable/android"
        android:visibility="gone" />

    <EditText
        android:id="@+id/edittext"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:singleLine="true" />

</LinearLayout>

I've also tried many of the suggestions below, including PravinCG's (RelativeLayout with alignTop/alignBottom):

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/edittext"
        android:layout_alignTop="@+id/edittext"
        android:scaleType="centerInside"
        android:src="@drawable/android"
        android:visibility="visible" />

    <EditText
        android:id="@+id/edittext"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/image"
        android:hint="@string/username"
        android:singleLine="true" />

</RelativeLayout>

But the result is exactly the same.

I've tried playing with the EditText's background padding, intrinsic height, but to no avail.

The EditText's background drawable is different among Android versions/ROMs, and I want to support them all.

How can I make this alignment pixel perfect on any android version (and style)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

童话 2025-01-14 16:49:24

最终找到了一个合适的解决方案,可以跨不同的 Android 版本/ROM/风格进行扩展。

主要问题是 EditText 的背景可绘制本身具有透明填充:
在此处输入图像描述

另外,我注意到这种透明填充在不同的 Android 之间存在很大差异版本/ROM/样式(例如,库存 ICS 根本没有透明填充)。

总而言之,我的原始代码将 ImageView 与 EditText 正确对齐。然而,我真正想要的是将我的 ImageView 与 EditText 背景的可见部分对齐。

为了实现这一点,我扫描了从 EditText 的背景可绘制对象创建的位图。我从上到下和从下到上扫描它以找到完全透明线的数量,并将这些值用作我的 ImageView 的顶部/底部填充。在我的 N1 上,所有这一切持续花费的时间不到 5 毫秒。代码如下:

if(editor.getBackground() != null) {
    int width = editor.getWidth();
    int height = editor.getHeight();
    Drawable backgroundDrawable = editor.getBackground().getCurrent();

    // Paint the editor's background in our bitmap
    Bitmap tempBitmap =  Bitmap.createBitmap(width, height, Config.ARGB_4444);
    backgroundDrawable.draw(new Canvas(tempBitmap));

    // Get the amount of transparent lines at the top and bottom of the bitmap to use as padding
    int topPadding = countTransparentHorizontalLines(0, height, tempBitmap);
    int bottomPadding = countTransparentHorizontalLines(height-1, -1, tempBitmap);

    // Discard the calculated padding if it means hiding the image
    if(topPadding + bottomPadding > height) {
        topPadding = 0;
        bottomPadding = 0;
    }

    tempBitmap.recycle();

    // Apply the padding
    image.setPadding(0, topPadding, 0, bottomPadding);
}

private int countTransparentHorizontalLines(int fromHeight, int toHeight, Bitmap bitmap) {
    int transparentHorizontalLines = 0;
    int width = bitmap.getWidth();
    int currentPixels[] = new int[width];
    boolean fullyTransparentLine = true;

    boolean heightRising = (fromHeight < toHeight);
    int inc =  heightRising ? 1 : -1;

    for(int height = fromHeight; heightRising ? (height < toHeight) : (toHeight < height); height+=inc) {
        bitmap.getPixels(currentPixels, 0, width, 0, height, width, 1);

        for(int currentPixel : currentPixels) {
            if(currentPixel != Color.TRANSPARENT && Color.alpha(currentPixel) != 255) {
                fullyTransparentLine = false;
                break;
            }
        }

        if(fullyTransparentLine)
            transparentHorizontalLines++;
        else
            break;
    }

    return transparentHorizontalLines;
}

它的作用就像一个魅力!

它有效!

Finally found a suitable solution that scales across different Android versions/ROMs/styles.

The main problem is that the EditText's background drawable itself has transparent padding:
enter image description here

Also, I've noticed this transparent padding varies a lot between different Android versions/ROMs/styles (stock ICS, for instance, has no transparent padding at all).

In a mid-way conclusion, my original code properly alignes my ImageView with my EditText. However, what I really want is to align my ImageView with the visible part of the EditText's background.

To achieve this, I scan a Bitmap I create from my EditText's background drawable. I scan it top-bottom and bottom-up to find the amount of fully transparent lines and use those values as top/bottom padding for my ImageView. All this consistently takes less than 5ms on my N1. Here's the code:

if(editor.getBackground() != null) {
    int width = editor.getWidth();
    int height = editor.getHeight();
    Drawable backgroundDrawable = editor.getBackground().getCurrent();

    // Paint the editor's background in our bitmap
    Bitmap tempBitmap =  Bitmap.createBitmap(width, height, Config.ARGB_4444);
    backgroundDrawable.draw(new Canvas(tempBitmap));

    // Get the amount of transparent lines at the top and bottom of the bitmap to use as padding
    int topPadding = countTransparentHorizontalLines(0, height, tempBitmap);
    int bottomPadding = countTransparentHorizontalLines(height-1, -1, tempBitmap);

    // Discard the calculated padding if it means hiding the image
    if(topPadding + bottomPadding > height) {
        topPadding = 0;
        bottomPadding = 0;
    }

    tempBitmap.recycle();

    // Apply the padding
    image.setPadding(0, topPadding, 0, bottomPadding);
}

private int countTransparentHorizontalLines(int fromHeight, int toHeight, Bitmap bitmap) {
    int transparentHorizontalLines = 0;
    int width = bitmap.getWidth();
    int currentPixels[] = new int[width];
    boolean fullyTransparentLine = true;

    boolean heightRising = (fromHeight < toHeight);
    int inc =  heightRising ? 1 : -1;

    for(int height = fromHeight; heightRising ? (height < toHeight) : (toHeight < height); height+=inc) {
        bitmap.getPixels(currentPixels, 0, width, 0, height, width, 1);

        for(int currentPixel : currentPixels) {
            if(currentPixel != Color.TRANSPARENT && Color.alpha(currentPixel) != 255) {
                fullyTransparentLine = false;
                break;
            }
        }

        if(fullyTransparentLine)
            transparentHorizontalLines++;
        else
            break;
    }

    return transparentHorizontalLines;
}

And it works like a charm!

it works!

荒人说梦 2025-01-14 16:49:24

您需要将 RelativeLayoutandroid:align_bottomandroid:align_Top 属性一起使用。不过我不是在写代码。

You need to use RelativeLayout with android:align_bottom and android:align_Top attribute. I am not writing the code though.

初熏 2025-01-14 16:49:24

您是否尝试过 EditTextsetCompoundDrawables() 方法。

您可以尝试使用 Drawable 上的 setBounds() 方法或使用 setCompoundDrawablesWithInstrinsicBounds() 方法来设置内在边界。

这应该适用于所有设备。

Have you tried the setCompoundDrawables() methods for the EditText.

You can try setting the intrinsic bounds using the setBounds() method on the Drawable or by using the setCompoundDrawablesWithInstrinsicBounds() method.

This should work on all devices.

把时间冻结 2025-01-14 16:49:24

要摆脱 EditText 中的填充,只需使用自定义图像作为背景...带有一些阴影的矩形就足够了...或任何您喜欢的...并将背景分配给 EditText 使用

android:background="@drawable/myBackground"

To get rid of the padding in the EditText, just use a custom image as background... rectangle with some shadow is enough... or whatever you like... and assign the background to the EditText using

android:background="@drawable/myBackground"
二手情话 2025-01-14 16:49:24

使用 android:layout_centerInParent = true 编辑文本并查看它是否有效?

use android:layout_centerInParent = true for edit text and see weather it works?

夏至、离别 2025-01-14 16:49:24

删除editText和ImageView的属性android:gravity =“center”并将线性布局的重力属性设置为center_vertically。

remove editText's and ImageView's properties android:gravity="center" and set gravity property of linearlayout to center_vertically.

你的他你的她 2025-01-14 16:49:24

我使用了一种快速解决方法,只需将以下内容添加到 EditText,即可将 EditText 向下移动 2dp:

android:layout_marginBottom="-2dp"
android:layout_marginTop="2dp"

I used a quick workaround by simply moving the EditText down 2dp by simply adding the following to the EditText:

android:layout_marginBottom="-2dp"
android:layout_marginTop="2dp"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文