Android自定义View仿IOS圆盘时间选择器
程序员文章站
2023-12-06 16:40:52
通过自定义view实现仿ios实现滑动两端的点选择时间的效果
效果图
自定义的view代码
public class ring_slide2 exte...
通过自定义view实现仿ios实现滑动两端的点选择时间的效果
效果图
自定义的view代码
public class ring_slide2 extends view { private static final double radian = 180 / math.pi; private int max_progress; // 设置最大进度 private int cur_progress; //设置锚点1当前进度 private int cur_progress2; //设置锚点2进度 private int bottom_color;//设置底色 private int circle_color; //设置圆的颜色(锚点) private int slide_color; //设置滑动过的颜色 private float ring_width; //圆环的宽度 private double cur_angle; //当前锚点1旋转角度 private double cur_angle2; //当前锚点2的旋转角度 private float ring_radius;//圆环的半径 private final int[] arrcolorcircle = new int[]{0xffffde37, 0xffffa400}; private int main_width; //圆的宽度 private float mwheelcurx, mwheelcury; //圆的位置 private float mwheelcurx2, mwheelcury2; //圆2的位置 private paint circle_paint; //圆环的画笔 private paint select_paint;//选中的画笔 private paint dot1; //圆点1 private paint dot2; //圆点2 private context context; private onseekbarchangelistener changelistener,changelistener2; public ring_slide2(context context) { this(context,null); } public ring_slide2(context context, attributeset attrs) { this(context, attrs,0); } public ring_slide2(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); this.context=context; initattrs(attrs,defstyleattr); initpadding(); //初始化画笔 initpaints(); } //初始化属性 private void initattrs(attributeset attrs, int defstyle){ typedarray typedarray = getcontext().obtainstyledattributes(attrs, r.styleable.cricle_slide, defstyle, 0); max_progress=typedarray.getint(r.styleable.cricle_slide_max_progress,720); cur_progress=typedarray.getint(r.styleable.cricle_slide_cur_progress,420); cur_progress2=typedarray.getint(r.styleable.cricle_slide_cur_progress2,540); if (cur_progress > max_progress) cur_progress = max_progress; if (cur_progress2 > max_progress) cur_progress2 = max_progress; bitmap bitmap = bitmapfactory.decoderesource(context.getresources(), r.mipmap.select_sun_bg2); main_width= bitmap.getwidth(); ring_width=typedarray.getfloat(r.styleable.cricle_slide_ring_width,main_width); bottom_color=typedarray.getcolor(r.styleable.cricle_slide_bottom_color,getcolor(r.color.select_main_bg_color)); circle_color=typedarray.getcolor(r.styleable.cricle_slide_circle_color,getcolor(r.color.duration)); slide_color=typedarray.getcolor(r.styleable.cricle_slide_slide_color,getcolor(r.color.time)); typedarray.recycle(); } //初始化边距 private void initpadding(){ int paddingleft = getpaddingleft(); int paddingtop = getpaddingtop(); int paddingright = getpaddingright(); int paddingbottom = getpaddingbottom(); int paddingstart = 0, paddingend = 0; if (build.version.sdk_int >= 17) { paddingstart = getpaddingstart(); paddingend = getpaddingend(); } int maxpadding = math.max(paddingleft, math.max(paddingtop, math.max(paddingright, math.max(paddingbottom, math.max(paddingstart, paddingend))))); setpadding(maxpadding, maxpadding, maxpadding, maxpadding); } private void initpaints(){ /* 圆环的画笔 */ circle_paint=new paint(paint.anti_alias_flag); circle_paint.setantialias(true); circle_paint.setcolor(bottom_color); circle_paint.setstyle(paint.style.stroke); circle_paint.setstrokewidth(ring_width); /* 选中区域的画笔 */ select_paint=new paint(paint.anti_alias_flag); select_paint.setshader(new sweepgradient(0, 0, arrcolorcircle, null)); /*select_paint.setcolor(circle_color);*/ select_paint.setantialias(true); select_paint.setstyle(paint.style.stroke); select_paint.setstrokewidth(ring_width); // 画锚点 dot1 = new paint(paint.anti_alias_flag); dot1.setcolor(circle_color); dot1.setantialias(true); dot1.setstyle(paint.style.fill); // 画锚点2 dot2 = new paint(paint.anti_alias_flag); dot2.setcolor(slide_color); dot2.setantialias(true); dot2.setstyle(paint.style.fill); } //获取宽度 private float getdimen(int dimenid) { return getresources().getdimension(dimenid); } //获取颜色 @targetapi(build.version_codes.m) private int getcolor(int colorid) { final int version = build.version.sdk_int; if (version >= 23) { return getcontext().getcolor(colorid); } else { return contextcompat.getcolor(getcontext(), colorid); } } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); bitmap bitmap = bitmapfactory.decoderesource(context.getresources(), r.mipmap.setalarm_colock_bg); int height = bitmap.getheight()+main_width*2; int width = bitmap.getwidth()+main_width*2; int min = math.min(height, width); setmeasureddimension(min,min); initposition(); } private void initposition(){ //转换为360度 cur_angle=(double) cur_progress / max_progress*360.0; cur_angle2=(double)cur_progress2 / max_progress*360.0; //计算初始化旋转的角度 double cos = -math.cos(math.toradians(cur_angle)); double cos2 = -math.cos(math.toradians(cur_angle2)); //根据旋转的角度来确定位置 makecurposition(cos); makecurposition2(cos2); //确定圆环的半径 ring_radius=(getmeasuredwidth() - getpaddingleft() - getpaddingright() - ring_width) / 2; } private void makecurposition(double cos){ //根据旋转的角度来确定圆的位置 //确定x点的坐标 mwheelcurx = calcxlocationinwheel(cur_angle, cos); //确定y点的坐标 mwheelcury=calcylocationinwheel(cos); } private void makecurposition2(double cos2){ //根据旋转的角度来确定圆的位置 //确定x点的坐标 mwheelcurx2 = calcxlocationinwheel(cur_angle2, cos2); //确定y点的坐标 mwheelcury2=calcylocationinwheel(cos2); } //确定x点的坐标 private float calcxlocationinwheel(double angle,double cos){ if (angle < 180) { return (float) (getmeasuredwidth() / 2 + math.sqrt(1 - cos * cos) * ring_radius); //math.sqrt正平分根 9-3 } else { return (float) (getmeasuredwidth() / 2 - math.sqrt(1 - cos * cos) * ring_radius); } } //确定y点的坐标 private float calcylocationinwheel(double cos) { return getmeasuredwidth() / 2 + ring_radius * (float) cos; } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); float left = getpaddingleft() + ring_width / 2; float top = getpaddingtop() + ring_width / 2; float right = canvas.getwidth() - getpaddingright() - ring_width / 2; float bottom = canvas.getheight() - getpaddingbottom() - ring_width / 2; float centerx = (left + right) / 2; float centery = (top + bottom) / 2; float wheelradius = (canvas.getwidth() - getpaddingleft() - getpaddingright()) / 2 - ring_width / 2; canvas.drawcircle(centerx, centery, wheelradius, circle_paint); //画选中区域 // canvas.drawarc(new rectf(left, top, right, bottom), (float) (math.pi * radian + math.acos(cur_angle) * radian), (float) (math.abs(cur_angle-cur_angle2)), false, select_paint); log.i("tag","第一个的角度="+cur_angle); log.i("tag","第一个的角度2="+cur_angle2); float begin=0; //圆弧的起点位置 float stop=0; if(cur_angle>180 && cur_angle>cur_angle2 ){ //180 -- 360 begin=(float) (-math.abs(cur_angle-360)-90); stop=(float) math.abs(math.abs(cur_angle-360)+cur_angle2); log.i("tag","begin="+begin); log.i("tag","stop="+stop); }else if(cur_angle>cur_angle2){ begin=(float) cur_angle-90; stop=(float)(360-(cur_angle-cur_angle2)); }else { begin=(float) cur_angle-90; stop=(float) math.abs(cur_angle-cur_angle2); } canvas.drawarc(new rectf(left, top, right, bottom), begin,stop, false, select_paint); //画锚点 画圆 canvas.drawcircle(mwheelcurx, mwheelcury, ring_width/2, dot1); //画锚点 画圆 canvas.drawcircle(mwheelcurx2, mwheelcury2, ring_width/2, dot2); log.i("tag","锚点1y"+mwheelcury+"锚点1x"+mwheelcurx); log.i("tag","锚点2y"+mwheelcury2+"锚点1x"+mwheelcurx2); } @override public boolean ontouchevent(motionevent event) { float x = event.getx(); float y = event.gety(); int flag=0; //判断是否触控到两个点中的其中某个点 if(ismovedot2(x,y)){ flag=2; }else if(ismovedot1(x,y)){ flag=1; } /* if(ismovedot1(x,y)){ flag=1; }else if(ismovedot2(x,y)){ flag=2; }*/ if(event.getaction()==motionevent.action_move || ismovedot1(x,y) ==true || ismovedot2(x,y)==true ){ log.i("tag","进入x="+x+"进入y="+y); //通过触摸点算出cos角度值 float cos = calculatecos(x, y); // 通过反三角函数获得角度值 double angle; //获取滑动的角度 if (x < getwidth() / 2) { // 滑动超过180度 angle = math.pi * radian + math.acos(cos) * radian; //通过计算得到滑动的角度值 } else { // 没有超过180度 angle = math.pi * radian - math.acos(cos) * radian; //pi 周长比直径 返回弧角度的余弦值 } if(flag==1){ cur_angle=angle; cur_progress=getselectedvalue(cur_angle); makecurposition(cos); if (changelistener != null) { changelistener.onchanged(this, cur_progress); } }else if(flag==2){ cur_angle2=angle; cur_progress2=getselectedvalue(cur_angle2); makecurposition2(cos); if (changelistener2 != null) { changelistener2.onchanged(this, cur_progress2); } } invalidate(); return true; }else { return super.ontouchevent(event); } } private boolean ismovedot1(float x,float y){ float dot1x = math.abs(mwheelcurx - x); float dot1y = math.abs(mwheelcury - y); if(dot1x<30 && dot1y<30){ return true; }else{ return false; } } private boolean ismovedot2(float x,float y){ float dot1x = math.abs(mwheelcurx2 - x); float dot1y = math.abs(mwheelcury2 - y); if(dot1x<30 && dot1y<30){ return true; }else{ return false; } } //拿到切斜角的cos值 private float calculatecos(float x, float y){ float width = x - getwidth() / 2; float height = y - getheight() / 2; float slope = (float) math.sqrt(width * width + height * height); return height / slope; } private int getselectedvalue(double mcurangle) { //角度转进度 return math.round(max_progress * ((float) mcurangle / 360)); //四舍五入 } public void setonseekbarchangelistener(onseekbarchangelistener listener) { changelistener = listener; } public void setonseekbarchangelistener2(onseekbarchangelistener listener) { changelistener2 = listener; } public void initradian(int pro1,int pro2){ this.cur_progress=pro1; this.cur_progress2=pro2; invalidate(); } public interface onseekbarchangelistener { void onchanged(ring_slide2 seekbar, int curvalue); } }
自定义stayle样式,在values下新建sttrs.xml文件
<declare-styleable name="cricle_slide"> //设置最大进度 <attr name="max_progress" format="integer"></attr> //设置当前进度 <attr name="cur_progress" format="integer"></attr> //设置当前进度 <attr name="cur_progress2" format="integer"></attr> //设置底色 <attr name="bottom_color" format="color"></attr> //设置圆的颜色 <attr name="circle_color" format="color"></attr> //设置滑动的颜色 <attr name="slide_color" format="color"></attr> //圆环的宽度 (dimension是代表尺寸值) <attr name="ring_width" format="dimension"></attr> </declare-styleable>
以上所述是小编给大家介绍的android自定义view仿ios圆盘时间选择器,希望对大家有所帮助
上一篇: 高德地图点亮城市怎么查看? 高德地图查看手动点亮城市
下一篇: 补气血的汤普大全!