Android 仿苹果IOS6开关按钮
程序员文章站
2024-03-04 11:08:17
先给大家展示下效果图:
不知道大家对效果图感觉怎么样,个人觉还不错,感兴趣的朋友可以参考下实现代码哦。
public class togglebutton...
先给大家展示下效果图:
不知道大家对效果图感觉怎么样,个人觉还不错,感兴趣的朋友可以参考下实现代码哦。
public class togglebutton extends view { private springsystem springsystem; private spring spring ; /** */ private float radius; /** 开启颜色*/ private int oncolor = color.parsecolor("#4ebb7f"); /** 关闭颜色*/ private int offbordercolor = color.parsecolor("#dadbda"); /** 灰色带颜色*/ private int offcolor = color.parsecolor("#ffffff"); /** 手柄颜色*/ private int spotcolor = color.parsecolor("#ffffff"); /** 边框颜色*/ private int bordercolor = offbordercolor; /** 画笔*/ private paint paint ; /** 开关状态*/ private boolean toggleon = false; /** 边框大小*/ private int borderwidth = 2; /** 垂直中心*/ private float centery; /** 按钮的开始和结束位置*/ private float startx, endx; /** 手柄x位置的最小和最大值*/ private float spotminx, spotmaxx; /**手柄大小 */ private int spotsize ; /** 手柄x位置*/ private float spotx; /** 关闭时内部灰色带高度*/ private float offlinewidth; /** */ private rectf rect = new rectf(); /** 默认使用动画*/ private boolean defaultanimate = true; /** 是否默认处于打开状态*/ private boolean isdefaulton = false; private ontogglechanged listener; private togglebutton(context context) { super(context); } public togglebutton(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); setup(attrs); } public togglebutton(context context, attributeset attrs) { super(context, attrs); setup(attrs); } @override protected void ondetachedfromwindow() { super.ondetachedfromwindow(); spring.removelistener(springlistener); } public void onattachedtowindow() { super.onattachedtowindow(); spring.addlistener(springlistener); } public void setup(attributeset attrs) { paint = new paint(paint.anti_alias_flag); paint.setstyle(style.fill); paint.setstrokecap(cap.round); springsystem = springsystem.create(); spring = springsystem.createspring(); spring.setspringconfig(springconfig.fromorigamitensionandfriction(50, 7)); this.setonclicklistener(new onclicklistener() { @override public void onclick(view arg0) { toggle(defaultanimate); } }); typedarray typedarray = getcontext().obtainstyledattributes(attrs, r.styleable.togglebutton); offbordercolor = typedarray.getcolor(r.styleable.togglebutton_tboffbordercolor, offbordercolor); oncolor = typedarray.getcolor(r.styleable.togglebutton_tboncolor, oncolor); spotcolor = typedarray.getcolor(r.styleable.togglebutton_tbspotcolor, spotcolor); offcolor = typedarray.getcolor(r.styleable.togglebutton_tboffcolor, offcolor); borderwidth = typedarray.getdimensionpixelsize(r.styleable.togglebutton_tbborderwidth, borderwidth); defaultanimate = typedarray.getboolean(r.styleable.togglebutton_tbanimate, defaultanimate); isdefaulton = typedarray.getboolean(r.styleable.togglebutton_tbasdefaulton, isdefaulton); typedarray.recycle(); bordercolor = offbordercolor; if (isdefaulton) { toggleon(); } } public void toggle() { toggle(true); } public void toggle(boolean animate) { toggleon = !toggleon; takeeffect(animate); if(listener != null){ listener.ontoggle(toggleon); } } public void toggleon() { settoggleon(); if(listener != null){ listener.ontoggle(toggleon); } } public void toggleoff() { settoggleoff(); if(listener != null){ listener.ontoggle(toggleon); } } /** * 设置显示成打开样式,不会触发toggle事件 */ public void settoggleon() { settoggleon(true); } /** * @param animate asd */ public void settoggleon(boolean animate){ toggleon = true; takeeffect(animate); } /** * 设置显示成关闭样式,不会触发toggle事件 */ public void settoggleoff() { settoggleoff(true); } public void settoggleoff(boolean animate) { toggleon = false; takeeffect(animate); } private void takeeffect(boolean animate) { if(animate){ spring.setendvalue(toggleon ? 1 : 0); }else{ //这里没有调用spring,所以spring里的当前值没有变更,这里要设置一下,同步两边的当前值 spring.setcurrentvalue(toggleon ? 1 : 0); calculateeffect(toggleon ? 1 : 0); } } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { final int widthmode = measurespec.getmode(widthmeasurespec); final int heightmode = measurespec.getmode(heightmeasurespec); int widthsize = measurespec.getsize(widthmeasurespec); int heightsize = measurespec.getsize(heightmeasurespec); resources r = resources.getsystem(); if(widthmode == measurespec.unspecified || widthmode == measurespec.at_most){ widthsize = (int) typedvalue.applydimension(typedvalue.complex_unit_dip, 50, r.getdisplaymetrics()); widthmeasurespec = measurespec.makemeasurespec(widthsize, measurespec.exactly); } if(heightmode == measurespec.unspecified || heightsize == measurespec.at_most){ heightsize = (int) typedvalue.applydimension(typedvalue.complex_unit_dip, 30, r.getdisplaymetrics()); heightmeasurespec = measurespec.makemeasurespec(heightsize, measurespec.exactly); } super.onmeasure(widthmeasurespec, heightmeasurespec); } @override protected void onlayout(boolean changed, int left, int top, int right, int bottom) { super.onlayout(changed, left, top, right, bottom); final int width = getwidth(); final int height = getheight(); radius = math.min(width, height) * 0.5f; centery = radius; startx = radius; endx = width - radius; spotminx = startx + borderwidth; spotmaxx = endx - borderwidth; spotsize = height - 4 * borderwidth; spotx = toggleon ? spotmaxx : spotminx; offlinewidth = 0; } simplespringlistener springlistener = new simplespringlistener(){ @override public void onspringupdate(spring spring) { final double value = spring.getcurrentvalue(); calculateeffect(value); } }; private int clamp(int value, int low, int high) { return math.min(math.max(value, low), high); } @override public void draw(canvas canvas) { // rect.set(0, 0, getwidth(), getheight()); paint.setcolor(bordercolor); canvas.drawroundrect(rect, radius, radius, paint); if(offlinewidth > 0){ final float cy = offlinewidth * 0.5f; rect.set(spotx - cy, centery - cy, endx + cy, centery + cy); paint.setcolor(offcolor); canvas.drawroundrect(rect, cy, cy, paint); } rect.set(spotx - 1 - radius, centery - radius, spotx + 1.1f + radius, centery + radius); paint.setcolor(bordercolor); canvas.drawroundrect(rect, radius, radius, paint); final float spotr = spotsize * 0.5f; rect.set(spotx - spotr, centery - spotr, spotx + spotr, centery + spotr); paint.setcolor(spotcolor); canvas.drawroundrect(rect, spotr, spotr, paint); } /** * @param value */ private void calculateeffect(final double value) { final float maptogglex = (float) springutil.mapvaluefromrangetorange(value, 0, 1, spotminx, spotmaxx); spotx = maptogglex; float mapofflinewidth = (float) springutil.mapvaluefromrangetorange(1 - value, 0, 1, 10, spotsize); offlinewidth = mapofflinewidth; final int fb = color.blue(oncolor); final int fr = color.red(oncolor); final int fg = color.green(oncolor); final int tb = color.blue(offbordercolor); final int tr = color.red(offbordercolor); final int tg = color.green(offbordercolor); int sb = (int) springutil.mapvaluefromrangetorange(1 - value, 0, 1, fb, tb); int sr = (int) springutil.mapvaluefromrangetorange(1 - value, 0, 1, fr, tr); int sg = (int) springutil.mapvaluefromrangetorange(1 - value, 0, 1, fg, tg); sb = clamp(sb, 0, 255); sr = clamp(sr, 0, 255); sg = clamp(sg, 0, 255); bordercolor = color.rgb(sr, sg, sb); postinvalidate(); } /** * @author thinkpad * */ public interface ontogglechanged{ /** * @param on = = */ public void ontoggle(boolean on); } public void setontogglechanged(ontogglechanged ontogglechanged) { listener = ontogglechanged; } public boolean isanimate() { return defaultanimate; } public void setanimate(boolean animate) { this.defaultanimate = animate; } }
别忘了自定义属性:attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="togglebutton"> <attr name="tbborderwidth" format="dimension"/> <attr name="tboffbordercolor" format="reference|color"/> <attr name="tboffcolor" format="reference|color"/> <attr name="tboncolor" format="reference|color"/> <attr name="tbspotcolor" format="reference|color"/> <attr name="tbanimate" format="reference|boolean"/> <attr name="tbasdefaulton" format="reference|boolean"/> </declare-styleable> </resources>
main.xml
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:toggle="http://schemas.android.com/apk/res-auto" android:orientation="vertical" > <linearlayout android:layout_margintop="10dp" android:layout_width="match_parent" android:gravity="center_horizontal" android:layout_height="wrap_content"> <com.example.ekikousei.view.togglebutton android:id="@+id/mtogglebutton01" android:layout_width="54dp" android:layout_height="30dp"> </com.example.ekikousei.view.togglebutton> </linearlayout> <linearlayout android:layout_margintop="10dp" android:layout_width="match_parent" android:gravity="center_horizontal" android:layout_height="wrap_content"> <com.example.ekikousei.view.togglebutton android:id="@+id/mtogglebutton02" android:layout_width="54dp" android:layout_height="30dp" toggle:tbborderwidth="2dp" toggle:tboffbordercolor="#000" toggle:tboffcolor="#ddd" toggle:tboncolor="#f00" toggle:tbspotcolor="#00f"> </com.example.ekikousei.view.togglebutton> </linearlayout> </linearlayout>
maintivity
public class mainactivity extends activity { private togglebutton mtogglebutton01; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); mtogglebutton01 = (togglebutton) findviewbyid(r.id.mtogglebutton01); mtogglebutton01.setontogglechanged(new togglebutton.ontogglechanged() { @override public void ontoggle(boolean on) { if (on) { toast.maketext(mainactivity.this, "打开", toast.length_short).show(); }else { toast.maketext(mainactivity.this, "默认关闭", toast.length_short).show(); } } }); } }
猛戳这里:studio点击下载
以上所述是小编给大家介绍的android 之仿苹果ios6开关按钮,希望对大家有所帮助
上一篇: 面试题 01.01. 判定字符是否唯一