自定义ImageView之圆形、圆角、爱心、动态旗帜效果

目    录(本篇字数:1555)

介绍

自定义ImageView代码

一、圆形ImageView效果

二、圆角矩形ImageView效果

三、椭圆形ImageView效果

四、三角形ImageView效果

五、爱心形ImageView效果

六、动态旗帜ImageView效果


  • 介绍

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

    既然这篇文章的代码是沿用上篇的自定义View之从零打造一个简单的图片显示控件 —— SimpleImageView,所以在此篇文章中,我就不再去介绍实现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://blog.csdn.net/smile_Running/article/details/81872881

@作者博客:_Xu2WeI

@更多博文:查看作者的更多博文

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的高校科研信息管理系统实现了操作日志管理、字典管理、反馈管理、公告管理、科研成果管理、科研项目管理、通知管理、学术活动管理、学院部门管理、科研人员管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让高校科研信息管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值