转载自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. 最佳时间买入卖出股票 Best Time to Buy and Sell Stock LeetCode

    LeetCode 我们有一个股票的数组,数组是每时间的钱,我们只能买入一次和卖出一次,求我们的最大收益. 我们知道了一个数组,那么我们可以在低价买入,然后高价卖出,但是需要知道我们的低价需要在高价之前 ...

  2. [hihoCoder]无间道之并查集

    题目大意: #1066 : 无间道之并查集 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 这天天气晴朗.阳光明媚.鸟语花香,空气中弥漫着春天的气息……额,说远了,总之, ...

  3. 读书笔记-你不知道的JS上-闭包与模块

    闭包定义 当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行. 看一段最简单的闭包代码: function foo() { var a = 2; //闭包 fun ...

  4. 如何阻止sql注入(pdo篇)

    Use prepared statements and parameterized queries. These are SQL statements that are sent to and par ...

  5. Spring框架学习之高级依赖关系配置(二)

    紧接着上篇内容,本篇文章将主要介绍XML Schema的简化配置和使用SpEL表达式语言来优化我们的配置文件. 一.基于XML Schema的简化配置方式 从Spring2.0以来,Spring支持使 ...

  6. YSlow---基于firebug的插件 ,用于网站页面性能的分析

    YSlow有什么用? YSlow可以对网站的页面进行分析,并告诉你为了提高网站性能,如何基于某些规则而进行优化. YSlow可以分析任何网站,并为每一个规则产生一个整体报告,如果页面可以进行优化,则Y ...

  7. 阿里云ecs遭到频繁的ddos攻击始末

    苦逼熬夜近俩月的时间搞出来个小东东,还指望它能给自己捞点~  结果刚上线没多久就遭到竞争对手疯狂的ddos攻击. 可怜的阿里云默认只能抗住5G的攻击,超出的直接黑洞,也是很无奈,然而能免费抗5G这在国 ...

  8. 兼容IE、火狐、谷歌的页面关闭事件

    <html> <head> <script language="javascript"> var blnCheckUnload = true; ...

  9. SElinux用户管理操作

    查看当前用户上下文 id -Z 查看登陆的用户和其对应的SELinux用户 semanage login -l 改变用户和SELinux的对应关系 semanage login -a选项能改变,-s用 ...

  10. PHP面试随笔

    1.常见的HTTP状态码: 1xx系列:代表请求已被接受,需要继续处理 2xx系列:代表请求已成功被服务器接收.理解并接受 200:表示请求已成功,请求所希望的响应头或数据体将随此响应返回 201:表 ...