圆形的ImageView
转载自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的更多相关文章
- Android开发之自定义圆形的ImageView的实现
android中的ImageView只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆形的图片,这个时候,我们就需要自定义ImageView了,其原理就是首先获取到图片的Bitmap,然 ...
- 自定义控件之 圆形 / 圆角 ImageView
一.问题在哪里? 问题来源于app开发中一个很常见的场景——用户头像要展示成圆的: 二.怎么搞? 机智的我,第一想法就是,切一张中间圆形透明.四周与底色相同.尺寸与头像相同的蒙板图片,盖在 ...
- Android圆形图片--ImageView
[ RoundImageView.java ] package com.dxd.roundimageview; import android.content.Context; import andro ...
- 圆形图片 ImageView
package com.example.m_evolution; import android.content.Context; import android.graphics.Bitmap; imp ...
- Android学习笔记-绘制圆形ImageView实例
现在很多的APP都很喜欢圆形的头像,这里就简单的写个圆形的ImageView~ 第三方圆形ImageView控件: RoundedImageView CircleImageView 实现代码: 自定义 ...
- Android之圆形头像裁切
PS:今天项目测试组发现,百度地图定位的数据坐标位置是正确的,但是显示的数据是错误的.最后查来查去发现,那个商厦在百度地图上根本就没有那条数据,这让我如何显示,当初就推崇使用高德地图定位,上面的数据量 ...
- 圆形的Volley.NetworkImageView控件的实现
github上有个开源项目CircleImageView,可以简单的实现一个圆形的ImageView,就像qq头像那样. NetworkImageView是volley中的一个组件,可以方便的加载网络 ...
- xml 实现圆形图 和 椭圆形图
1. 效果图 2.圆形图 <ImageView android:layout_width="wrap_content" android:layout_height=" ...
- Android开发之自定义圆角矩形图片ImageView的实现
android中的ImageView只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆角矩形的图片,这个时候,我们就需要自定义ImageView了,其原理就是首先获取到图片的Bitmap ...
随机推荐
- win10 uwp 绑定多数据
经常我们需要绑定的数据有多个,当添加到集合控件的对象类型结构比较复杂,我们希望自己来定义排版布局,这时可以使用ItemTemplate用资源的定义 现在有数据 public class caddres ...
- 张高兴的 Windows 10 IoT 开发笔记:红外温度传感器 MLX90614
GitHub : https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/MLX90614
- 什么是git?window下安装git
一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以 ...
- faster-rcnn中ROI_POOIING层的解读
在没有出现sppnet之前,RCNN使用corp和warp来对图片进行大小调整,这种操作会造成图片信息失真和信息丢失.sppnet这个模型推出来之后(关于这个网络的描述,可以看看之前写的一篇理解:ht ...
- 【转】ATA Secure Erase
ATA Secure Erase This procedure describes how to use the hdparm command to issue a Secure Erase ...
- Linux CentOS7 安装 Mysql5.7.19
第二次安装会安装失败 1.先停止mysql服务 service mysql stop 2.检查是否卸载干净 find / -name mysql 多用几个命令检查,不要删到其他组件的 ...
- 阻塞队列BlockingQueue
BlockingQueue最终会有四种状况,抛出异常.返回特殊值.阻塞.超时,下表总结了这些方法: 抛出异常 特殊值 阻塞 超时 插入 add(e) offer(e) put(e) offer(e, ...
- 217. Contains Duplicate (leetcode)
Given an array of integers, find if the array contains any duplicates. Your function should return t ...
- LeetCode 204. Count Primes (质数的个数)
Description: Count the number of prime numbers less than a non-negative number, n. 题目标签:Hash Table 题 ...
- 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 ...