将 ImageView 与 EditText 水平对齐

Posted

技术标签:

【中文标题】将 ImageView 与 EditText 水平对齐【英文标题】:Align ImageView with EditText horizontally 【发布时间】:2012-03-11 10:40:19 【问题描述】:

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

XML 部分非常简单:

<LinearLayout
    android:layout_
    android:layout_
    android:orientation="horizontal" >

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

    <EditText
        android:id="@+id/edittext"
        android:layout_
        android:layout_
        android:singleLine="true" />

</LinearLayout>

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

<RelativeLayout
    android:layout_
    android:layout_
    android:gravity="center_vertical"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/image"
        android:layout_
        android:layout_
        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_
        android:layout_
        android:layout_toRightOf="@id/image"
        android:hint="@string/username"
        android:singleLine="true" />

</RelativeLayout>

但结果完全一样。

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

EditText的背景drawable在Android版本/ROM之间是不同的,我想支持它们。

如何在任何 android 版本(和样式)上使这种对齐像素完美

【问题讨论】:

您应该根据您的屏幕分辨率分配编辑文本和图像的布局权重,通过分配布局权重,它在任何横向或纵向模式下看起来都很完美..试试它可能会起作用。 使用填充可能会导致不同分辨率的不可预测的结果。 【参考方案1】:

终于找到了适合不同 Android 版本/ROM/样式的解决方案。

主要问题是 EditText 的背景可绘制对象本身具有透明填充:

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

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

为了实现这一点,我扫描了从 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;

它就像一个魅力!

【讨论】:

很高兴看到你有 sol,但每次在运行时创建它时,当你有很多带有 editText 的图像时,你有没有在 xml 中找到任何其他 sol 或其他东西?跨度> 不幸的是,没有。仔细阅读我的回答,相信您会明白为什么使用纯 XML 无法做到这一点。 当你有一个编辑文本框图像时,我们可以很容易地做到这一点,文本框的默认图像创建一个问题,是的,我也看到了你的任务和你的答案......你做了一个我必须说做得很好。但是当你有足够的数据时它并不好,我会建议使用你自己的图像作为文本框的背景,编辑位图可能会在运行时占用大量内存。 是的,在这种情况下,使用您自己的没有哑边框的背景图像会是一个更好的解决方案!在这种情况下它只是一个,我们想要支持各种原生 EditText 的......所以我们必须求助于这个。【参考方案2】:

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

【讨论】:

你不需要 :) 无论如何,它不起作用。我已将它们包装在 RelativeLayout 中,并将 android:layout_alignTopandroid:layout_alignBottom 添加到 ImageView。结果与上面的屏幕截图相同。 能贴一下,你是怎么实现的? 能否在ImageView和TextView中同时添加android:layout_alignParentTop="true"android:layout_alignParentBottom="true" 在这种情况下,您可以为 editText 添加透明背景。不过,让我尝试一下。 我刚刚测试过,你是对的,存在导致此问题的固有边距。删除它的唯一方法是在您的编辑文本中使用android:background="#FFFF0000"。您可以选择任何颜色,但它不会是默认样式。【参考方案3】:

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

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

这应该适用于所有设备。

【讨论】:

我会尝试并报告结果。谢谢! 我试过了,效果不错。然而,这并不是我真正想要实现的目标......使用setCompoundDrawables() 将图像放在 EditText 中,而不是紧挨着它。无论如何,谢谢,+1 替代方法! 哦...好的。好吧,如果您找不到合适的解决方案,您可以尝试将背景设置为EditText,其中包含图像并填充EditText 以避免它或Drawable 作为compoundDrawable 和单独的背景drawable打折可绘制区域 我找到了合适的解决方案!检查我的答案,看看我是如何做到的。感谢您的帮助,让我学习如何使用 setCompoundDrawables() ;)【参考方案4】:

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

将背景分配给 EditText >
android:background="@drawable/myBackground"

【讨论】:

【参考方案5】:

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

【讨论】:

不幸的是,没有。此外,android:layout_centerInParent 对 LinearLayouts 没有影响。 它的 LinearLayout 所以android:layout_centerInParent 不起作用。 这不能很好地跨分辨率/操作系统版本/ROM 扩展。【参考方案6】:

去掉editText和ImageView的属性android:gravity="center",将linearlayout的gravity属性设置为center_vertically。

【讨论】:

试过了,但我得到了相同的结果。谢谢!【参考方案7】:

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

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

【讨论】:

如果您的目标设备数量较少,此解决方法将有效。 Note 3 中的 2dp 比 Ace 2 中的多。

以上是关于将 ImageView 与 EditText 水平对齐的主要内容,如果未能解决你的问题,请参考以下文章

如何在edittext中设置ImageView [复制]

使用 ImageView 动态创建多个 EditText 并将 ImageView 点击值设置为 EditText 并从 EditText 获取值

ImageView 上的透明背景 EditText 不会显示光标

第三方开源库-->EditText & ImageView

Android踩坑日记:RecyclerView中EditText和ImageView的ViewHolder复用坑

Android踩坑日记:RecyclerView中EditText和ImageView的ViewHolder复用坑