博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义ImageView之圆形、圆角、爱心、动态旗帜效果
阅读量:5863 次
发布时间:2019-06-19

本文共 8268 字,大约阅读时间需要 27 分钟。

目    录(本篇字数:1555)


  • 介绍

    今天,我们继续上篇文章提到的自定义View之实现一个简单显示图片的SimpleImageView控件来进一步实现:CircleImageView(圆形效果)、LoveImageView(爱心效果)、FlagImageView(动态旗帜效果)、RoundRectImageView(圆角矩形效果)等等显示不同形状的图片。

    既然这篇文章的代码是沿用上篇的,所以在此篇文章中,我就不再去介绍实现SimpleImageView的步骤了。那么,我默认你已经实现了上篇文章所简述的代码。那就开始吧,我们先来看一波实现的效果图。

    这篇的内容主要运用了Paint类的着色器(Shader)效果,通过BitmapShader类为图片设置了Shader,然后再通过画笔(Paint)将其画出,利用画笔绘制各种各样的图形。

    实现效果的对比图:

  • 自定义ImageView代码

/** * @Created by xww. * @Creation time 2018/8/8. */public class CircleImageView extends View {    private Paint mPaint;    private Drawable mDrawable;    private BitmapShader mBitmapShader;    private int mWidth;    private int mHeight;    @SuppressLint("Recycle")    private void initAttrs(AttributeSet attrs) {        if (attrs != null) {            TypedArray array = null;            try {                array = getContext().obtainStyledAttributes(attrs, R.styleable.RectangleImageView);                mDrawable = array.getDrawable(R.styleable.RectangleImageView_src);                if (mDrawable == null) {                    throw new NullPointerException("drawable is not null");                }                mWidth = mDrawable.getIntrinsicWidth();                mHeight = mDrawable.getIntrinsicHeight();            } finally {                if (array != null) {                    array.recycle();                }            }        }    }    public CircleImageView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        mPaint = new Paint();        mPaint.setAntiAlias(true);        initAttrs(attrs);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));    }    @SuppressLint("DrawAllocation")    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (mDrawable == null) {            return;        }        final int width = canvas.getWidth();        final int height = canvas.getHeight();        /**         * 绘制圆形图片         */        mBitmapShader = new BitmapShader(drawableToBitmap(mDrawable), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        mPaint.setShader(mBitmapShader);        canvas.drawCircle(width / 2, height / 2, width / 2, mPaint);    }    private int measureWidth(int widthMeasureSpec) {        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        switch (widthMode) {            case MeasureSpec.UNSPECIFIED:             case MeasureSpec.AT_MOST:                 break;            case MeasureSpec.EXACTLY:                 mWidth = widthSize;                break;        }        return mWidth;    }    private int measureHeight(int heightMeasureSpec) {        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        switch (heightMode) {            case MeasureSpec.UNSPECIFIED:            case MeasureSpec.AT_MOST:                break;            case MeasureSpec.EXACTLY:                mHeight = heightSize;                break;        }        return mHeight;    }    private Bitmap drawableToBitmap(Drawable drawable) {        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;        Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, config);        Canvas canvas = new Canvas(bitmap);        drawable.setBounds(0, 0, mWidth, mHeight);        drawable.draw(canvas);        return bitmap;    }}

一、圆形ImageView效果

    关键代码:

    利用canvas绘制圆形的效果。

/**         * 绘制圆形图片         */        mBitmapShader = new BitmapShader(drawableToBitmap(mDrawable), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        mPaint.setShader(mBitmapShader);        canvas.drawCircle(width / 2, height / 2, width / 2, mPaint);

二、圆角矩形ImageView效果

    关键代码:

    将本段代码替换圆形图片的注释部分的代码即可。

/**         * 绘制圆角矩形图片         */        mBitmapShader = new BitmapShader(drawableToBitmap(mDrawable), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        mPaint.setShader(mBitmapShader);        canvas.drawRoundRect(0, 0, width, height, 50, 50, mPaint);

三、椭圆形ImageView效果

    关键代码:

    将本段代码替换圆形图片的注释部分的代码即可。

mBitmapShader = new BitmapShader(drawableToBitmap(mDrawable), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        mPaint.setShader(mBitmapShader);        canvas.drawOval(0, 0, width-50, height-200, mPaint);

四、三角形ImageView效果

    关键代码:

    简单介绍一下,利用路径来绘制一个三角形,将本段代码替换圆形图片的注释部分的代码即可。

mBitmapShader = new BitmapShader(drawableToBitmap(mDrawable), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        mPaint.setShader(mBitmapShader);        Path path = new Path();        path.moveTo(width / 2, 0);        path.lineTo(width, height);        path.lineTo(0, height);        path.close();        canvas.drawPath(path, mPaint);

五、爱心形ImageView效果

    关键代码:

    将本段代码替换圆形图片的注释部分的代码即可。

/**         * 调用drawLove()方法         */        mBitmapShader = new BitmapShader(drawableToBitmap(mDrawable), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        mPaint.setShader(mBitmapShader);        drawLove(canvas);    private void drawLove(Canvas canvas) {        //(17*(x^2))-(16*abs(x)*y)+(17*(y^2))<255 x(-5,5) y(-5,5) (心形函数方程式)        int loveWidth = 500;//心型宽度,必须是偶数        int oneLine = loveWidth / 2;//一条轴长度        float scale = oneLine / 5f;//实际坐标比上方程式坐标,倍数        for (int i = 0; i < oneLine; i++) {            for (int j = 0; j < oneLine; j++) {                //根据表达式xy的范围,所以要把坐标系的范围也缩小                float xf = i / scale;                float yf = j / scale;                if ((17 * Math.pow(xf, 2) - 16 * Math.abs(xf) * yf + 17 * Math.pow(yf, 2)) < 255) {                    canvas.drawPoint(250 - xf * scale, 250 - yf * scale, mPaint);                    canvas.drawPoint(250 + xf * scale, 250 - yf * scale, mPaint);                }                if ((17 * Math.pow(xf, 2) - 16 * Math.abs(xf) * (-yf) + 17 * Math.pow(yf, 2)) < 255) {                    canvas.drawPoint(250 - xf * scale, 250 + yf * scale, mPaint);                    canvas.drawPoint(250 + xf * scale, 250 + yf * scale, mPaint);                }            }        }    }

六、动态旗帜ImageView效果

    关键代码:

    将本类所有代码,替换之前的代码即可。

/** * 旗帜飘扬的动态效果 * * @Created by xww. * @Creation time 2018/8/8. */public class FlagImageView extends View {    //将图像分成多少格    private int WIDTH = 200;    private int HEIGHT = 200;    //交点坐标的个数    private int COUNT = (WIDTH + 1) * (HEIGHT + 1);    //用于保存COUNT的坐标    //x0, y0, x1, y1......    private float[] verts = new float[COUNT * 2];    //用于保存原始的坐标    private float[] orig = new float[COUNT * 2];    private Bitmap mBitmap;    private float K = 1;    public FlagImageView(Context context, AttributeSet attrs) {        super(context, attrs);        initView();    }    private void initView() {        int index = 0;        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_loop_ad_2);        float bmWidth = mBitmap.getWidth();        float bmHeight = mBitmap.getHeight();        for (int i = 0; i < HEIGHT + 1; i++) {            float fy = bmHeight * i / HEIGHT;            for (int j = 0; j < WIDTH + 1; j++) {                float fx = bmWidth * j / WIDTH;                //X轴坐标 放在偶数位                verts[index * 2 + 0] = fx;                orig[index * 2 + 0] = verts[index * 2 + 0];                //Y轴坐标 放在奇数位                //向下移动200                verts[index * 2 + 1] = fy + 200;                orig[index * 2 + 1] = verts[index * 2 + 1];                index += 1;            }        }    }    @Override    protected void onDraw(Canvas canvas) {        for (int i = 0; i < HEIGHT + 1; i++) {            for (int j = 0; j < WIDTH + 1; j++) {                verts[(i * (WIDTH + 1) + j) * 2 + 0] += 0;                //利用正弦函数的周期性                float offsetY = (float) Math.sin((float) j / WIDTH * 2 * Math.PI + K * 2 * Math.PI);                verts[(i * (WIDTH + 1) + j) * 2 + 1] = orig[(i * (WIDTH + 1) + j) * 2 + 1] + offsetY * 50;            }        }        //平移 旗帜飘扬效果        K += 0.1F;        canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, verts, 0, null, 0, null);        invalidate();    }}

    当然,如果你觉得效果还不够丰富,可以自己利用画布绘制更多的形状效果。

©原文链接:

@作者博客:

@更多博文:

转载于:https://www.cnblogs.com/xww0826/p/10359498.html

你可能感兴趣的文章
编译器处理警告、错误 #pragma GCC diagnostic ignored "-Wunused"
查看>>
Qtablevies获取内容
查看>>
jdk安装配置具体分析
查看>>
[转]ASP.NET Core 中间件详解及项目实战
查看>>
eclipse编辑窗口不见了(打开左边的java、xml文件,中间不会显示代码)
查看>>
iOS动画篇:核心动画
查看>>
第一篇:《UNIX 环境高级编程》编译环境的搭建
查看>>
人脸关键点检测算法
查看>>
事物与数据库锁的关系(锁只是数据库事物一方面)
查看>>
《Qt数据类型》--QByteArray,QString,int,hex之间的转化
查看>>
vue知识点总结
查看>>
linux-程序发布脚本
查看>>
ps如何制作gif(窗口->动画)(导出:存储为Web和设备所用格式)
查看>>
git: windows git ssh keys生成
查看>>
如何快速搜索SQL数据库数据和对象
查看>>
[原][osg][oe]分析一块倾斜摄影瓦片的数据
查看>>
正则表达式在线生成工具
查看>>
第二章 排序 || 第18节 有序矩阵查找练习题
查看>>
虚拟机“锁定文件失败”、“打不开磁盘”或者“它所依赖的某个快照磁盘”的解决办法...
查看>>
MyBatis动态创建表
查看>>