转载自gitHub的ImageView,因为本身就是可用的,也没什么好说的,拷贝回去用就是了,可以设置除了背景,还可以设置边框什么的,比起CardView设置圆角,功能更加强大。

import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;

public class AnimateCheckBox extends View {

    ;
    private static final int DEFAULT_LINE_COLOR = Color.WHITE;
    private static final int DEFAULT_CHECKED_COLOR = Color.RED;
    private static final int DEFAULT_UNCHECK_COLOR = Color.GRAY;
    ;
    ;
    private Paint mCirclePaint;
    private Paint mLinePaint;

    private int radius;                    //圆的半径
    private int width, height;             //控件宽高
    private int cx, cy;                    //圆心xy坐标
]; //对号的3个点的坐标
    private float correctProgress;
    private float downY;
    private boolean isChecked;
    private boolean toggle;
    private boolean isAnim;

    private int animDuration = DEFAULT_ANIM_DURATION;
    private int unCheckColor = DEFAULT_UNCHECK_COLOR;
    private int circleColor = DEFAULT_CHECKED_COLOR;
    private int correctColor = DEFAULT_LINE_COLOR;
    private int correctWidth = DEFAULT_LINE_WIDTH;

    private OnCheckedChangeListener listener;

    public AnimateCheckBox(Context context) {
        this(context, null);
    }

    public AnimateCheckBox(Context context, AttributeSet attrs) {
        );
    }

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

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.);

        circleColor = a.getColor(R.styleable.AnimateCheckBox_checkedColor, DEFAULT_CHECKED_COLOR);
        unCheckColor = a.getColor(R.styleable.AnimateCheckBox_unCheckColor, DEFAULT_UNCHECK_COLOR);
        correctColor = a.getColor(R.styleable.AnimateCheckBox_lineColor, DEFAULT_LINE_COLOR);
        correctWidth = a.getDimensionPixelSize(R.styleable.AnimateCheckBox_lineWidth, DEFAULT_LINE_WIDTH);
        animDuration = a.getInteger(R.styleable.AnimateCheckBox_animDuration, DEFAULT_ANIM_DURATION);

        a.recycle();

        init(context);

    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public AnimateCheckBox(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 初始化
     *
     * @param context
     */
    private void init(Context context) {

        mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCirclePaint.setStyle(Paint.Style.FILL);
        mCirclePaint.setColor(circleColor);

        mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mLinePaint.setStyle(Paint.Style.FILL);
        mLinePaint.setColor(correctColor);
        mLinePaint.setStrokeWidth(correctWidth);

        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isChecked) {
                    hideCorrect();
                } else {
                    showCheck();
                }
            }
        });
    }

    /**
     * 返回当前选中状态
     *
     * @return
     */
    public boolean isChecked() {
        return isChecked;
    }

    /**
     * 设置当前选中状态
     *
     * @param checked
     */
    public void setChecked(boolean checked) {
        if (isChecked && !checked) {
            hideCorrect();
        } else if (!isChecked && checked) {
            showCheck();
        }
    }

    public void setUncheckStatus() {
        isChecked = false;
        radius = DEFAULT_RADIUS;
        ;
        invalidate();
    }

    /**
     * 确定尺寸坐标
     *
     * @param w
     * @param h
     * @param oldw
     * @param oldh
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        height = width = Math.min(w - getPaddingLeft() - getPaddingRight(), h - getPaddingBottom() - getPaddingTop());
        ;
        ;

        float r = height / 2f;
        ] = r / 2f + getPaddingLeft();
        ] = r + getPaddingTop();

        ] = r * 5f / 6f + getPaddingLeft();
        ] = r + r / 3f + getPaddingTop();

        ] = r * 1.5f + getPaddingLeft();
        ] = r - r / 3f + getPaddingTop();
        DEFAULT_RADIUS = radius = (int) (height * 0.125f);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        float f = (radius - height * 0.125f) / (height * 0.5f); //当前进度
        mCirclePaint.setColor(evaluate(f, unCheckColor, circleColor));
        canvas.drawCircle(cx, cy, radius, mCirclePaint); //画圆

        //画对号
) {
            if (correctProgress < 1 / 3f) {
                ] + (] - ]) * correctProgress;
                ] + (] - ]) * correctProgress;
                canvas.drawLine(], ], x, y, mLinePaint);
            } else {
                ] + (] - ]) * correctProgress;
                ] + (] - ]) * correctProgress;
                canvas.drawLine(], ], ], ], mLinePaint);
                canvas.drawLine(], ], x, y, mLinePaint);
            }
        }
    }

    /**
     * 设置圆的颜色
     *
     * @param color
     */
    public void setCircleColor(int color) {
        circleColor = color;
    }

    /**
     * 设置对号的颜色
     *
     * @param color
     */
    public void setLineColor(int color) {
        mLinePaint.setColor(color);
    }

    /**
     * 设置未选中时的颜色
     *
     * @param color
     */
    public void setUnCheckColor(int color) {
        unCheckColor = color;
    }

    private int evaluate(float fraction, int startValue, int endValue) {
        ) {
            return startValue;
        }
        ) {
            return endValue;
        }
        int startInt = startValue;
        ) & 0xff;
        ) & 0xff;
        ) & 0xff;
        int startB = startInt & 0xff;

        int endInt = endValue;
        ) & 0xff;
        ) & 0xff;
        ) & 0xff;
        int endB = endInt & 0xff;

        ) | ((startR + () | ((startG + () | ((startB + (int) (fraction * (endB - startB))));
    }

    /**
     * 处理触摸事件触发动画
     */

    private class OnChangeStatusListener implements OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    downY = event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    float dy = event.getRawY() - downY;
                    ) { //滑过一半触发
                        toggle = true;
                    } else {
                        toggle = false;
                    }
                    break;
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP:
                    if (toggle) {
                        if (isChecked) {
                            hideCorrect();
                        } else {
                            showCheck();
                        }
                    }
                    break;
            }
            return true;
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void showUnChecked() {
        if (isAnim) {
            return;
        }

        isAnim = true;
        ValueAnimator va = ValueAnimator.ofFloat(, ).setDuration(animDuration);
        va.setInterpolator(new LinearInterpolator());
        va.start();
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue(); // 0f ~ 1f
                radius = (int) ((1 - value) * height * 0.375f + height * 0.125f);
                ) {
                    isChecked = false;
                    isAnim = false;
                    if (listener != null) {
                        listener.onCheckedChanged(AnimateCheckBox.this, false);
                    }
                }
                invalidate();
            }
        });
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void showCheck() {
        if (isAnim) {
            return;
        }
        isAnim = true;
        ValueAnimator va = ValueAnimator.ofFloat(, ).setDuration(animDuration);
        va.setInterpolator(new LinearInterpolator());
        va.start();
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue(); // 0f ~ 1f
                radius = (int) (value * height * 0.37f + height * 0.125f);
                ) {
                    isChecked = true;
                    isAnim = false;
                    if (listener != null) {
                        listener.onCheckedChanged(AnimateCheckBox.this, true);
                    }
                    showCorrect();
                }
                invalidate();
            }
        });
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void showCorrect() {
        if (isAnim) {
            return;
        }
        isAnim = true;
        ValueAnimator va = ValueAnimator.ofFloat(, ).setDuration(animDuration);
        va.setInterpolator(new LinearInterpolator());
        va.start();
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue(); // 0f ~ 1f
                correctProgress = value;
                invalidate();
                ) {
                    isAnim = false;
                }
            }
        });
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void hideCorrect() {
        if (isAnim) {
            return;
        }
        isAnim = true;
        ValueAnimator va = ValueAnimator.ofFloat(, ).setDuration(animDuration);
        va.setInterpolator(new LinearInterpolator());
        va.start();
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue(); // 0f ~ 1f
                correctProgress = 1 - value;
                invalidate();
                ) {
                    isAnim = false;
                    showUnChecked();
                }
            }
        });
    }

    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        this.listener = listener;
    }

    public interface OnCheckedChangeListener {
        void onCheckedChanged(View buttonView, boolean isChecked);
    }
}

style参数设置
<declare-styleable name="CircleImageView">
    <attr name="civ_border_width" format="dimension" />
    <attr name="civ_border_color" format="color" />
    <attr name="civ_border_overlay" format="boolean" />
    <attr name="civ_fill_color" format="color" />
</declare-styleable>

XML布局文件添加代码
xmlns:app="http://schemas.android.com/apk/res-auto"


圆形的ImageView的更多相关文章

  1. Android开发之自定义圆形的ImageView的实现

    android中的ImageView只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆形的图片,这个时候,我们就需要自定义ImageView了,其原理就是首先获取到图片的Bitmap,然 ...

  2. 自定义控件之 圆形 / 圆角 ImageView

    一.问题在哪里? 问题来源于app开发中一个很常见的场景——用户头像要展示成圆的:       二.怎么搞? 机智的我,第一想法就是,切一张中间圆形透明.四周与底色相同.尺寸与头像相同的蒙板图片,盖在 ...

  3. Android圆形图片--ImageView

    [ RoundImageView.java ] package com.dxd.roundimageview; import android.content.Context; import andro ...

  4. 圆形图片 ImageView

    package com.example.m_evolution; import android.content.Context; import android.graphics.Bitmap; imp ...

  5. Android学习笔记-绘制圆形ImageView实例

    现在很多的APP都很喜欢圆形的头像,这里就简单的写个圆形的ImageView~ 第三方圆形ImageView控件: RoundedImageView CircleImageView 实现代码: 自定义 ...

  6. Android之圆形头像裁切

    PS:今天项目测试组发现,百度地图定位的数据坐标位置是正确的,但是显示的数据是错误的.最后查来查去发现,那个商厦在百度地图上根本就没有那条数据,这让我如何显示,当初就推崇使用高德地图定位,上面的数据量 ...

  7. 圆形的Volley.NetworkImageView控件的实现

    github上有个开源项目CircleImageView,可以简单的实现一个圆形的ImageView,就像qq头像那样. NetworkImageView是volley中的一个组件,可以方便的加载网络 ...

  8. xml 实现圆形图 和 椭圆形图

    1. 效果图 2.圆形图 <ImageView android:layout_width="wrap_content" android:layout_height=" ...

  9. Android开发之自定义圆角矩形图片ImageView的实现

    android中的ImageView只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆角矩形的图片,这个时候,我们就需要自定义ImageView了,其原理就是首先获取到图片的Bitmap ...

随机推荐

  1. word2vec 数学原理

    word2vec 是 Google 于 2013 年推出的一个用于获取词向量的开源工具包.我们在项目中多次使用到它,但囿于时间关系,一直没仔细探究其背后的原理. 网络上 <word2vec 中的 ...

  2. PHP 操作 进程时相关 信号的具体含义

    SIGQUIT    建立CORE文件终止进程,并且生成core文件SIGILL     建立CORE文件       非法指令SIGTRAP    建立CORE文件       跟踪自陷SIGBUS ...

  3. dubbo的架构

    dubbo架构图如下所示: 节点角色说明: Provider: 暴露服务的服务提供方. Consumer: 调用远程服务的服务消费方. Registry: 服务注册与发现的注册中心. Monitor: ...

  4. 顺序线性表 ---- ArrayList 源码解析及实现原理分析

    原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7738888.html ------------------------------------ ...

  5. python 模块的概念介绍

    模块 模块:本质就是一个.py文件分为三部分:内置模块.第三方模块,自定义模块 模块: 顶层文件 python模块python模块可以将代码量较大的程序分割成多个有组织的.彼此独立但又能互相交互的代码 ...

  6. MySQL(十六)之MySQL用户管理

    一.MySQL用户管理概述 MySQL是一个多用户的数据库,MYSQL的用户可以分为两大类: 超级管理员用户(root),拥有全部权限 普通用户,由root创建,普通用户只拥有root所分配的权限 二 ...

  7. common lisp和scheme的区别

    1. 在Common Lisp 眼中,一个符号的symbol-value 和symbol-function 是不一样的,而Scheme对两者不作区分.在Scheme 里面,变量只有唯一对应的值,它可以 ...

  8. 如何让Vim成为我们的神器

    Vim 是 Linux 系统上的最著名的文本/代码编辑器,也是早年的 Vi 编辑器的加强版,而 gVim 则是其 Windows 版.它的最大特色是完全使用键盘命令进行编辑,脱离了鼠标操作虽然使得入门 ...

  9. GPU的线程模型和内存模型

    遇见C++ AMP:在GPU上做并行计算 Written by Allen Lee I see all the young believers, your target audience. I see ...

  10. 暑假练习赛 004 E Joint Stacks(优先队列模拟)

    Joint StacksCrawling in process... Crawling failed Time Limit:4000MS     Memory Limit:65536KB     64 ...