如何在RelativeLayout中给图像添加背景?

3

注意:我已经将这个问题报告给了Android项目的错误报告中心,链接如下:http://code.google.com/p/android/issues/detail?id=39159。同时请查看接受的赏金答案,不幸的是,解决方法是使用绝对布局(即指定'dp'而不是'wrap_content'等)来修复此问题。

当我在图片上放置背景时,我遇到了非常奇怪的行为。为了向您演示问题,我已经大大简化了代码。我的做法是在RelativeLayout中放置一个图像,并使用一个背景。似乎给RelativeLayout添加填充会导致图像的背景被错误地绘制。Wrap_content似乎出了问题。

首先,这是演示问题的代码。请注意,如果不使用LinearLayout,只给ImageView添加背景也会看到同样的行为,但这真的更好地演示了问题。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:padding="5dp" >
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/black_bg" >
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:src="@drawable/red_rectangle" />
        </LinearLayout>
    </RelativeLayout>
</FrameLayout>

这是black_bg的xml文件:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#FF000000"/>
</shape> 

这里是红色矩形: red_rectangle 请注意,这是一个参考图像,以展示问题。我的实际图像有细节,因此不能使用.9.png格式。
这是问题的屏幕截图: Rendering error 您可以看到,图像宽度小于linearlayout,尽管linearlayout的宽度设置为“wrap_content”。如果我将relativelayout填充设置为0dp,则此问题会消失。
我希望这里提供的资源集相对容易理解,因此如果需要,人们可以自己尝试一下。
供参考,我正在使用此功能在图像周围提供边框,因此我可以使线性布局(或图像本身)具有填充,但在这种情况下问题仍然存在。
编辑:似乎我可能需要更多上下文来回答这个问题,因为答案集中在如何提供此边框方面。以下是更详细布局的屏幕截图。我起初不想包含这个截图,因为它会增加问题的复杂性: Screenshot 您在此处看到的前5dp填充用于此整个项目(relativelayout)的内容。然后,如我最初所说的那样,“我可以使线性布局(或图像本身)具有填充”,除了您在relativelayout中看到的第一个填充之外。目前,此布局不应显示任何边框。

图片的分辨率是你的问题。使用可以扩展的图像,例如矢量(.9png 图像),或者简单地使用 shape - Vinay W
请注意,这是一个参考图像,用于演示问题。我的实际图像有细节,因此不能是.9.png格式。 - Sam
我可以看出你没有得到预期的结果,但是你的需求不够清晰。你期望的布局是什么样子的,以及你想如何使用它? - karn
预期的布局是看不到黑色。然后对于某些布局,我可以在LinearLayout上设置填充(或者在ImageView本身上设置,如果我将背景放在那里),从而得到边框。 - Sam
5个回答

4

问题似乎在于图像(在图像视图中)和设置为背景(在线性布局中)的图像具有不同的拉伸属性。设置为背景的图像不一定保持纵横比,而图像中的图像则倾向于保持它。 当您将布局的高度设为60 dp时,图像会缩小并保持纵横比,留下两侧的黑色条纹。 这对我有用:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:padding="5dp" >
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/black_bg" >
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="60dp"
                android:src="@drawable/asd"
                android:scaleType="fitXY"
                 />
        </LinearLayout>
    </RelativeLayout>
</FrameLayout>

1
android:scaleType="fitXY" 属性在图像视图中明确地使图像在不遵循纵横比的情况下进行拉伸。 - iHateCoding
很抱歉,这个没有起作用。红色矩形可绘制对象被严重拉伸了。 - Sam
如果您采用我的原始示例并完全删除背景,然后使用图形布局工具并单击红色矩形的右侧,您将看到LinearLayout仍未包装内容。 - Sam

1

我不知道为什么那里会显示额外的黑色补丁。你试过运行这个应用程序吗?UI编辑器有一些缺陷,特别是涉及到ImageView时。

现在对于图像周围的边框,将背景和填充设置到ImageView本身。不需要LinearLayout。添加缩放类型属性,值为"centerInside"

 <ImageView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:padding="5dp"
      android:layout_centerInParent="true"
      android:adjustViewBounds="true" 
      android:src="@drawable/red_rectangle"
      android:background="#000" 
      android:scaleType="centerInside"/> 

是的,我认为我在手机上运行时发现了这个问题。我的问题相当长,所以您可能错过了这一点:首先,这是演示问题的代码。请注意,即使不使用线性布局,只给ImageView设置背景也会看到相同的行为,但这确实更好地证明了问题。 - Sam
android:scaleType="centerInside" - Ron

1

我认为这是一个很好的错误候选者!

无论如何,我理解您想要通过此布局实现的目标。问题在于设置RelativeLayout的高度。我不会要求您包装内容!只需将高度设置为60dp,填充为5dp,然后进一步将LinearLayout的高度设置为50dp,即60-2*5 :)

最后,为了获得边框,请向LinearLayout添加5dp的填充,并将ImageView的高度设置为50dp - 2*5 = 40dp

这将完美地工作


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:padding="5dp" >
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:padding="5dp"
            android:background="@drawable/black_bg" >
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:adjustViewBounds="true"
                android:src="@drawable/red_rectangle" />
        </LinearLayout>
    </RelativeLayout>
</FrameLayout>


啊,像那样使用绝对布局违背了我的道德准则,哈哈,但我想这可能是唯一的解决方法...感谢您花时间寻找解决方案并认真阅读问题,非常感激。我已经不再从事这个项目,但会尽快测试这个解决方案。我想我会将其作为 Android 项目中的一个 bug 提交。链接很快就会出现在这里。在两个月的开发中,我发现了三个布局错误,Google 应该雇佣我 :-P - Sam
这个答案已经被授予悬赏。非常感谢您仔细阅读和测试我的问题,Sherif。很遗憾布局必须以这种方式完成,但至少我从另一个来源得到了这个错误的确认。 - Sam
看起来RelativeLayout可以被移除,它的padding可以用LinearLayout的margin代替,而LinearLayout可能可以改为FrameLayout - Miha_x64

0

尝试这个……

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:padding="5dp" >
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/black_bg"
            **android:padding="5dp"**
            >
            <ImageView
                **android:layout_width="fill_parent"
                android:layout_height="fill_parent"**
                android:adjustViewBounds="true"
                android:src="@drawable/red_rectangle" />
        </LinearLayout>
    </RelativeLayout>
</FrameLayout>

让你的图像视图看起来像这样...

<ImageView 
            android:id="@+id/imageViewMyicon"
            android:layout_width="30dp"
            android:background="@drawable/myiconbackground"
            android:layout_height="30dp"
            android:src="@drawable/myicon"
            android:contentDescription="@string/my_icon"
            />

在你的drawable文件夹中,有一个名为myiconbackground.xml的文件。

<shape xmlns:android="http://schemas.android.com/apk/res/android" 
       android:shape="rectangle" 
       android:padding="10dp">
    <solid android:color="#0D95BD"/>
        <corners android:radius="5dp"/>
        <padding android:left="2dp" android:right="2dp" android:top="2dp" android:bottom="2dp"/>
</shape>

我检查过这个,对我来说有效,对你也应该有效。


0
“仅供参考,我正在使用此方法为图像提供边框。”
“添加一个可绘制的'border.xml'文件。”
<shape xmlns:android:"http://schemas.android.com/apk/res/android" android:shape:"rectangle">
 <stroke android:width="5dp" android:color="#FF000000" />
 <padding android:left="5dp" android:top="5dp" android:right="5dp" android:bottom="5dp" />
</shape>

将您的ImageView背景设置为此可绘制对象。
并且让我们简化您的布局并将ImageView居中:
<?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:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:layout_centerInParent="true"
                android:adjustViewBounds="true" 
                android:src="@drawable/red_rectangle"
                android:background="@drawable/border" /> 
</RelativeLayout> 

不,虽然是一个有趣的实验。给这个LinearLayout设置背景会产生这样的结果:http://i.imgur.com/OxN7b.png(请注意,我改为了FF0000FF,以便您可以看到此内容)。将此背景设置为ImageView并删除LinearLayout后,就会得到此结果:http://i.imgur.com/lLFZK.png - Sam
也许还需要将ImageView的padding设置为"5dp"。为什么你的RelativeLayout设置为固定高度?你的Image资源的高度是多少?我会对我的答案做更多的编辑。 - CSmith
我给ImageView添加了padding,但没有得到任何结果。我需要一个特定的高度。这是列表中的许多项之一。图片资源比RelativeLayout大。 - Sam
将填充元素添加到可绘制对象中。请查看https://dev59.com/-3A75IYBdhLWcg3wf5JV,我的初始答案已经接近了。 - CSmith
填充元素是为了我的周围布局,其中包含文本等内容。然后将进一步添加填充元素到LinearLayout(或ImageView)以提供边框。这是一个简化的布局,以显示问题。 - Sam
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接