转载自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. win10 uwp 绑定多数据

    经常我们需要绑定的数据有多个,当添加到集合控件的对象类型结构比较复杂,我们希望自己来定义排版布局,这时可以使用ItemTemplate用资源的定义 现在有数据 public class caddres ...

  2. 张高兴的 Windows 10 IoT 开发笔记:红外温度传感器 MLX90614

    GitHub : https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/MLX90614

  3. 什么是git?window下安装git

    一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以 ...

  4. faster-rcnn中ROI_POOIING层的解读

    在没有出现sppnet之前,RCNN使用corp和warp来对图片进行大小调整,这种操作会造成图片信息失真和信息丢失.sppnet这个模型推出来之后(关于这个网络的描述,可以看看之前写的一篇理解:ht ...

  5. 【转】ATA Secure Erase

    ATA Secure Erase     This procedure describes how to use the hdparm command to issue a Secure Erase  ...

  6. Linux CentOS7 安装 Mysql5.7.19

    第二次安装会安装失败 1.先停止mysql服务  service mysql stop 2.检查是否卸载干净   find / -name mysql      多用几个命令检查,不要删到其他组件的 ...

  7. 阻塞队列BlockingQueue

    BlockingQueue最终会有四种状况,抛出异常.返回特殊值.阻塞.超时,下表总结了这些方法: 抛出异常 特殊值 阻塞 超时 插入 add(e) offer(e) put(e) offer(e, ...

  8. 217. Contains Duplicate (leetcode)

    Given an array of integers, find if the array contains any duplicates. Your function should return t ...

  9. LeetCode 204. Count Primes (质数的个数)

    Description: Count the number of prime numbers less than a non-negative number, n. 题目标签:Hash Table 题 ...

  10. LeetCode 121. Best Time to Buy and Sell Stock (买卖股票的最好时机)

    Say you have an array for which the ith element is the price of a given stock on day i. If you were ...