像 Google+ 一样的可选圆形图片视图

6

如何创建一个可选的圆形ImageView,就像当前Google+应用程序中用于个人资料图片的那样?

这就是我所指的:

Example

上面的图像未被选择,下面的图像已被选择。

我试图完全复制个人资料图片。

我的工作进展:

loadedImage是显示的Bitmap

mImageView.setBackground(createStateListDrawable());
mImageView.setImageBitmap(createRoundImage(loadedImage));

使用的方法:

private Bitmap createRoundImage(Bitmap loadedImage) {
    Bitmap circleBitmap = Bitmap.createBitmap(loadedImage.getWidth(), loadedImage.getHeight(), Bitmap.Config.ARGB_8888);

    BitmapShader shader = new BitmapShader(loadedImage, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(shader);

    Canvas c = new Canvas(circleBitmap);
    c.drawCircle(loadedImage.getWidth() / 2, loadedImage.getHeight() / 2, loadedImage.getWidth() / 2, paint);

    return circleBitmap;
}

private StateListDrawable createStateListDrawable() {
    StateListDrawable stateListDrawable = new StateListDrawable();

    OvalShape ovalShape = new OvalShape();
    ShapeDrawable shapeDrawable = new ShapeDrawable(ovalShape);
    stateListDrawable.addState(new int[] { android.R.attr.state_pressed }, shapeDrawable);
    stateListDrawable.addState(StateSet.WILD_CARD, shapeDrawable);

    return stateListDrawable;
}
< p > ImageView 的大小为 imageSizePx,而图像的大小为 imageSizePx - 3。这意味着背景应该重叠在图像上。但是,这并不起作用。


1
你有所指的截图吗? - CommonsWare
也许这能帮到你。https://dev59.com/IWcs5IYBdhLWcg3wHwfU - Reactgular
@CommonsWare 稍等一下。 - Leandros
图像按钮?https://dev59.com/xG865IYBdhLWcg3wOcHy - Reactgular
5个回答

6

感谢@CommonsWare提供的提示,这是一个非常简单的解决方案。

Bitmap的尺寸: imageSizePx - 3DP
ImageView的尺寸: imageSizePx

mImageView.setBackground(createStateListDrawable(imageSizePx));
mImageView.setImageBitmap(loadedImage);

private StateListDrawable createStateListDrawable(int size) {
    StateListDrawable stateListDrawable = new StateListDrawable();

    OvalShape ovalShape = new OvalShape();
    ovalShape.resize(size, size);
    ShapeDrawable shapeDrawable = new ShapeDrawable(ovalShape);
    shapeDrawable.getPaint().setColor(getResources().getColor(R.color.somecolor));

    stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, shapeDrawable);
    stateListDrawable.addState(new int[]{android.R.attr.state_focused}, shapeDrawable);
    stateListDrawable.addState(new int[]{}, null);

    return stateListDrawable;
}

3
假设你所说的“可选”是指“可勾选,像复选框一样”,那么这可能是使用StateListDrawable的某个CompoundButton,其中包含常规状态和已选状态用于“SkillOverflow”前景图像背后的背景。
你可以使用uiautomatorviewer查看Google+实际使用的小部件。

我所说的“可选择性”,是指我有触摸反馈。我使用“可选择性”这个术语,因为默认的xml也被命名为“selectable_background_holo”。对于造成的困惑,我感到抱歉。 - Leandros
很可能。问题是如何创建与上面示例中相同的效果?只有圆形形状的描边出现,而不是整个矩形ImageButton / ImageView被突出显示。 - Leandros
1
@Leandros:这将是我一直在提到的自定义StateListDrawable背景。使按钮看起来像按钮的是其背景,而该背景使用不同的图像呈现不同的状态(正常、按下、选定、已选中等)。 - CommonsWare
好的,没问题。这是个好主意。之前我考虑过将ImageView变成圆形,但是一个略微宽2像素的圆形StateListDrawable更好。现在问题来了,如何编写一个可按比例缩放的StateListDrawable程序呢? - Leandros
是的,我尝试过了,但它并没有按预期工作。填充完全被忽略了。我直接在ImageView上设置了填充。 - Leandros
显示剩余6条评论

2
您可以创建一个自定义视图扩展ImageView。重写onDraw方法,使用圆形区域裁剪画布并将图片绘制在画布上。以下是一个起点示例代码:
public class CircularImageView extends ImageView {
    /* constructors omitted for brevity ... */

    protected void onDraw(Canvas canvas) {
        int saveCount = canvas.save();

        // clip in a circle

        // draw image
        Drawable d = getDrawable();
        if (d != null) {
            d.draw(canvas);
        }

        // do extra drawing on canvas if pressed

        canvas.restoreToCount(saveCount);
    }
}

花些时间熟悉Android中的Canvas和其他2D绘图API。


0

0

我通过自定义ImageView并覆盖onDraw方法来实现这种效果,每当它检测到触摸事件时绘制一些类似于“边框”的东西。作为额外的奖励,还有一个选择器叠加层。希望你会发现这个视图很有用...

https://github.com/Pkmmte/CircularImageView

enter image description here


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