0

我正在寻找ImageView在 API 级别 14+ 上为元素(在本例中)添加细 (1dp) 边框的最简单、可靠的方法。

据我了解,层列表是做这类事情的方式。

所以,我有什么:

<ImageView
    android:id="@+id/overlay_main_character"
    android:layout_height="72dp"
    android:layout_width="72dp"        
    android:background="@drawable/image_border"
    />

在 Java 中,ImageView 被设置为显示这个 200x200 像素的图像 维基共享资源

并在res/drawable/image_border.xml

<!-- Adds thin (1dp) border, and nothing else. -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <shape android:shape="rectangle" >
            <stroke android:width="1dp" android:color="#FF000000" />
            <solid android:color="@android:color/transparent"/>
        </shape>
    </item>

    <item>
        <shape android:shape="rectangle">
            <padding android:top="1dp" />
            <padding android:bottom="1dp" />
            <padding android:left="1dp" />
            <padding android:right="1dp" />
        </shape>
    </item>

</layer-list>

它在测试设备(Galaxy Note,Android 4.1.2)上的样子:

在此处输入图像描述

缺少左边框和下边框。

我究竟做错了什么?我的图层列表方法是否不正确(或者可以简化)?或者这可以使用图层列表以外的其他方法来实现吗?

4

3 回答 3

5

您可以为您设置背景颜色ImageView并将填充设置为 1dp:

<ImageView
    android:id="@+id/overlay_main_character"
    android:layout_height="72dp"
    android:layout_width="72dp"        
    android:background="#F000"
    android:padding="1dp"
    />

它看起来像你想要的。

于 2013-11-06T13:04:55.283 回答
2

虽然此解决方案简单且总体上效果很好,但在通过网络(在后台线程中)获取图像的情况下,它有一个缺点。当图像仍在加载时,会显示一个黑色的大方块,这不一定是您想要的。

我的一位同事指出,在这种情况下,您可以这样做:FrameLayout在边框的图像“后面”添加一个,并将ImageView背景设置为白色(例如),如下所示:

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:color/black"
    android:padding="1dp">

    <ImageView
        android:id="@+id/overlay_main_character"
        android:layout_height="72dp"
        android:layout_width="72dp"
        android:background="@android:color/white" />

</FrameLayout>

在我们的例子中,进行中的外观会更好:

在此处输入图像描述


附录:自定义“边框图像”组件

实际上,除了 1dp 边框外,我们还希望在通过网络加载图像(alpha 0 -> 1)后对其进行动画显示;就像是:

imageView.setAlpha(0f); 
imageView.animate().alpha(1f).setDuration(500).start();

为了让动画看起来不错(至少在我们的应用程序中),背景应该是白色而不是黑色。

为了同时支持边框和动画,我必须在图像和外部(边框)FrameLayout 之间添加另一个FrameLayout(带有白色背景)。但是 XML 变得非常冗长,因此我们在 Java 中为此创建了一个自定义的可重用组件:“ BorderedImage ”。

package fi.company.product.ui.helpers;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import android.widget.ImageView;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;

/**
 * Custom ImageView (technically custom FrameLayout) with black 1dp border, 
 * white background and support for alpha animation (white -> image)
 *
 * @author Jonik, https://stackoverflow.com/a/19818328/56285
 */
public class BorderedImage extends FrameLayout {

    private ImageView imageView;

    public BorderedImage(Context context) {
        super(context);
        init(context);
    }

    public BorderedImage(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public BorderedImage(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context context) {
        // Outer FrameLayout for the black border
        setBackgroundColor(getResources().getColor(android.R.color.black));
        int padding1dp = (int) getResources().getDisplayMetrics().density
        setPadding(padding1dp, padding1dp, padding1dp, padding1dp);

        // Another FrameLayout for the white background 
        FrameLayout middleLayout = new FrameLayout(context);
        middleLayout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
        middleLayout.setBackgroundColor(getResources().getColor(android.R.color.white));
        addView(middleLayout);

        // The actual ImageView
        imageView = new ImageView(context);
        imageView.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
        middleLayout.addView(imageView);
    }

    public ImageView getImageView() {
        return imageView;
    }
}

当然,进一步自定义这个助手会很容易:例如,将边框和背景颜色作为构造函数参数传递。

现在,在 XML 中使用 BorderedImage 很简单:

<fi.company.product.ui.helpers.BorderedImage
    android:id="@+id/overlay_main_character"
    android:layout_height="72dp"
    android:layout_width="72dp" />
于 2013-11-06T17:11:02.880 回答
0
<LinearLayout
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:orientation="vertical"
   android:padding="1dp" >
   <ImageView
        android:id="@+id/overlay_main_character"
        android:layout_height="72dp"
        android:layout_width="72dp"        
        android:background="@drawable/image_border"
        />
于 2013-11-06T13:03:12.807 回答