我正在寻找一种最简单,最可靠的方法来为元素添加一个瘦(1dp)边框 - 在这种情况下ImageView
- 在API级别14 +上。
根据我的理解,图层列表是做这种事情的方法。
所以,我有:
<ImageView
android:id="@+id/overlay_main_character"
android:layout_height="72dp"
android:layout_width="72dp"
android:background="@drawable/image_border"
/>
在Java中,ImageView设置为显示this 200x200 px image (Wikimedia Commons)。
在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):
缺少左下边框。
我做错了什么?我的图层列表方法是否不正确(或者可以简化)?或者这可以使用除图层列表以外的其他东西来实现吗?
答案 0 :(得分:5)
您可以为ImageView
设置背景颜色,并将填充设置为1dp:
<ImageView
android:id="@+id/overlay_main_character"
android:layout_height="72dp"
android:layout_width="72dp"
android:background="#F000"
android:padding="1dp"
/>
它看起来像你想要的。
答案 1 :(得分:2)
尽管this solution很简单并且通常效果很好,但在通过网络(在后台线程中)获取图像的情况下,它有一个缺点。当图片仍在加载时,会显示大黑方块,这不一定是您想要的。
A colleague of mine指出,在这种情况下,您可以这样做:在边框的图像后面添加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 - &gt; 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;
}
}
当然,很容易进一步定制这个帮助器:例如,传递边框&amp;背景颜色作为构造函数参数。
现在,在XML中使用BorderedImage非常简单:
<fi.company.product.ui.helpers.BorderedImage
android:id="@+id/overlay_main_character"
android:layout_height="72dp"
android:layout_width="72dp" />
答案 2 :(得分: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"
/>