如何在Android的ImageView上制作卷曲边缘?

6

在此输入图像描述

我需要实现这个效果。

有谁知道我该如何实现?

能否用XML完成?如果不能,那么如何缩放这样形状的图像?


不确定,但这可能是使用一个形状为此的图像PNG完成的。您可以将卷曲的图像放在其他视图的顶部。 - Shivam Verma
我在考虑将背景设置为ImageView,因为在ImageView中处理图像比作为布局或TextView的背景更容易。 - kimv
@Shivam,在不同的屏幕尺寸上它会有不良的扩展性吗? - kimv
你可能需要自己制作这样的图像。创建一个9patch图像。如果你做得对,它将缩放那些不卷曲的部分。而卷曲的部分将保持不变。 - Max Zavernutiy
不,9patches 在这里无法帮助,应该使用自定义的Drawable类或者使用自定义Shape类的ShapeDrawable - pskink
显示剩余2条评论
2个回答

3
尝试使用我的类。它允许您设置任何类型的背景,并在图像上获得卷曲边缘效果:
/**
 * Created by GIGAMOLE on 01.07.2015.
 */
public class CurlyEdgesImageView extends ImageView {

    private int width;
    private int height;

    private ArrayList<FloatPoint> points = new ArrayList<>();

    private final Path curlyEdgesPath = new Path();
    private final Paint curlyEdgesPaint = new Paint(Paint.ANTI_ALIAS_FLAG) {
        {
            setDither(true);
        }
    };

    private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG) {
        {
            setDither(true);
            setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        }
    };

    private Canvas curlyEdgesCanvas;
    private Bitmap curlyEdgesBitmap;

    private Canvas canvas;
    private Bitmap bitmap;

    private float offset;
    private float curlyEdgesCount = 20f;

    public CurlyEdgesImageView(Context context) {
        super(context);
    }

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

    public CurlyEdgesImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        this.width = w;
        this.height = h;

        this.offset = this.width / (curlyEdgesCount * 2);

        bitmap = drawableToBitmap(getDrawable());
        canvas = new Canvas(bitmap);

        curlyEdgesBitmap = Bitmap.createBitmap(w, (int) offset, Bitmap.Config.ARGB_8888);
        curlyEdgesCanvas = new Canvas(curlyEdgesBitmap);

        drawCurlyEdges();

        canvas.drawBitmap(curlyEdgesBitmap,
                0,
                getHeight() - (int) offset,
                paint
        );

        super.onSizeChanged(w, h, oldw, oldh);
    }

    private void drawCurlyEdges() {
        final float innerOffset = curlyEdgesCount / offset;

        int counterY = 1;
        for (float i = -offset; i < this.width + offset; i += offset) {
            if (counterY++ % 2 == 0) {
                points.add(new FloatPoint(i + innerOffset, offset));
            } else {
                points.add(new FloatPoint(i + innerOffset, 0));
            }
        }

        points.add(new FloatPoint(this.width + offset, (int) offset * 2));
        points.add(new FloatPoint(-offset, (int) offset * 2));

        if (points.size() > 1) {
            FloatPoint prevPoint = null;
            for (int i = 0; i < points.size(); i++) {
                FloatPoint point = points.get(i);

                if (i == 0) {
                    curlyEdgesPath.moveTo(point.x, point.y);
                } else {
                    float midX = (prevPoint.x + point.x) / 2f;
                    float midY = (prevPoint.y + point.y) / 2f;

                    if (i == 1) {
                        curlyEdgesPath.lineTo(midX, midY);
                    } else {
                        curlyEdgesPath.quadTo(prevPoint.x, prevPoint.y, midX, midY);
                    }
                }
                prevPoint = point;
            }
            curlyEdgesPath.lineTo(prevPoint.x, prevPoint.y);
        }

        curlyEdgesCanvas.drawPath(curlyEdgesPath, curlyEdgesPaint);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(bitmap, 0, 0, null);
    }

    private Bitmap drawableToBitmap(final Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            return convertToMutable(getContext(), ((BitmapDrawable) drawable.mutate()).getBitmap());
        }

        final Bitmap bitmap = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return convertToMutable(getContext(), bitmap);
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public static Bitmap convertToMutable(final Context context, final Bitmap imgIn) {
        final int width = imgIn.getWidth(), height = imgIn.getHeight();
        final Bitmap.Config type = imgIn.getConfig();

        File outputFile = null;
        final File outputDir = context.getCacheDir();
        try {
            outputFile = File.createTempFile(Long.toString(System.currentTimeMillis()), null, outputDir);
            outputFile.deleteOnExit();

            final RandomAccessFile randomAccessFile = new RandomAccessFile(outputFile, "rw");
            final FileChannel channel = randomAccessFile.getChannel();
            final MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_WRITE, 0, imgIn.getRowBytes() * height);

            imgIn.copyPixelsToBuffer(map);
            imgIn.recycle();

            final Bitmap result = Bitmap.createBitmap(width, height, type);

            map.position(0);
            result.copyPixelsFromBuffer(map);

            channel.close();
            randomAccessFile.close();

            outputFile.delete();
            return result;
        } catch (final Exception e) {
        } finally {
            if (outputFile != null)
                outputFile.delete();
        }
        return null;
    }

    private class FloatPoint {
        public float x;
        public float y;

        private FloatPoint(float x, float y) {
            this.x = x;
            this.y = y;
        }
    }
}

enter image description here


@Gigamole 能够看到图像的卷曲效果,但之后无法使用 Glide 库加载图像。 - Gaurav Arora

2
  1. 创建一个名为wave_pattern_image的波浪图案切片
  2. 制作一个可重复的drawable对象
  3. 将该drawable对象设置为视图的背景

drawable/tilebg.xml

<?xml version="1.0" encoding="utf-8"?>
    <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
        android:src="@drawable/wave_pattern_image"
        android:tileMode="repeat" />

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