虽然此解决方案简单且总体上效果很好,但在通过网络(在后台线程中)获取图像的情况下,它有一个缺点。当图像仍在加载时,会显示一个黑色的大方块,这不一定是您想要的。
我的一位同事指出,在这种情况下,您可以这样做: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" />