、最近,在项目开发中需要用到开关按钮,因为业务需求,需要适应自己的Appstyle,所以决定亲自实操一遍,自定义一个控件。业务需求: 1.开关点击事件 2.开关滑动事件 3.涉及了动态测量绘制文本的宽高
方法/步骤
1、先上效果图,如下:
2、因为比较简单,没有自定义属性,注释比较完整,所以贴上完整代码给你们参考,有问题可以私聊。完整代码如下:
3、publicclassAuto幞洼踉残ButtonextendsViewimplementsView.OnTouchListene鸡堕樱陨r{ //开关背景图 privateBitmapbgBitmap;//开关按钮图 privateBitmapbtnBitmap;privatePaintpaint;//标记开关滑动的值 privateintleftDis=0;//标记开关滑动的最大值 privateintslidingMax;//设置开关对应的文本 privatefinalStringtext1="开";privatefinalStringtext2="关; //标记开关状态 privatebooleanmCurrent; //标记点击事件 privatebooleanisClickable; //标记滑动事件 privatebooleanisMove; //开关打开的事件监听器 privateSoftFloorListenersoftFloorListener; //开关关闭的事件监听器 privateHydropowerListenerhydropowerListener; //标记开关文本的宽度 floatwidth1,width2; //记录文本中心点cx1:绘制文本1的x坐标cx2:绘制文本2的x坐标 //cy记录绘制文本的高度 floatcx1,cy,cx2; //代码实例化需要的方法 publicAutoButton(Contextcontext){ this(context,null); } //在xml布局时需要用到的方法 publicAutoButton(Contextcontext,AttributeSetattrs){ this(context,attrs,0); } publicAutoButton(Contextcontext,AttributeSetattrs,intdefStyleAttr){ super(context,attrs,defStyleAttr); initView(); } //初始化数据 privatevoidinitView(){ //加载背景图 bgBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.bg_switchbutton); //加载开关按钮图btnBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.btn_switchbutton); paint=newPaint(); slidingMax=bgBitmap.getWidth()-btnBitmap.getWidth(); paint.setTextSize(35); //测量绘制文本1的宽度 width1=paint.measureText(text1); //测量文本的宽度 Paint.FontMetricsIntfontMetricsInt=paint.getFontMetricsInt(); cy=btnBitmap.getHeight()/2+(fontMetricsInt.descent-fontMetricsInt.ascent)/2; width2=paint.measureText(text2); cx2=(bgBitmap.getWidth()*2-btnBitmap.getWidth())/2-width2/2; paint.setAntiAlias(true); setOnTouchListener(this); } @Override protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){//根据加载图片设置控件的大小 setMeasuredDimension(bgBitmap.getWidth(),bgBitmap.getHeight()); } @Override protectedvoidonDraw(Canvascanvas){ super.onDraw(canvas); //绘制背景图 canvas.drawBitmap(bgBitmap,0,0,paint); //绘制按钮图 canvas.drawBitmap(btnBitmap,leftDis,0,paint); //根据不同状态绘制不同颜色,不同位置的文本 if(mCurrent){ paint.setColor(Color.WHITE); canvas.drawText(text2,cx2,cy,paint); paint.setColor(Color.BLACK); canvas.drawText(text1,cx1,cy,paint); }else{ paint.setColor(Color.WHITE); canvas.drawText(text1,cx1,cy,paint); paint.setColor(Color.BLACK); canvas.drawText(text2,cx2,cy,paint); } }//根据事件刷新视图 privatevoidflushView(){ mCurrent=!mCurrent; if(mCurrent){ leftDis=slidingMax; if(hydropowerListener!=null){ //按钮打开监听器 hydropowerListener.hydropower(); } }else{ leftDis=0; if(softFloorListener!=null){ //按钮关闭监听器 softFloorListener.softFloor(); } } invalidate(); }//startX标记手指按下的X坐标,lastX标记移动后的x坐标 //disX标记x方向移动的距离 floatstartX,lastX,disX; @Override publicbooleanonTouch(Viewv,MotionEventevent){switch(event.getAction()){caseMotionEvent.ACTION_DOWN: isClickable=true; startX=event.getX(); isMove=false; break; caseMotionEvent.ACTION_MOVE: lastX=event.getX(); disX=lastX-startX; //设置一个移动的阈值 if(Math.abs(disX)<5)break; isMove=true; isClickable=false; moveBtn(); startX=event.getX(); break; caseMotionEvent.ACTION_UP: //点击事件 if(isClickable){ flushView(); } //滑动事件 if(isMove){ if(leftDis>slidingMax/2){ mCurrent=false; }else{ mCurrent=true; } flushView(); } break; } returntrue;} //按钮滑动时的位置控制 privatevoidmoveBtn(){ leftDis+=disX; if(leftDis>slidingMax){ leftDis=slidingMax; }elseif(leftDis<0){ leftDis=0; } invalidate(); } //设置按钮打开监听器 publicvoidsetSoftFloorListener(SoftFloorListenersoftFloorListener){this.softFloorListener=softFloorListener; } //设置按钮关闭监听器publicvoidsetHydropowerListener(HydropowerListenerhydropowerListener){ this.hydropowerListener=hydropowerListener; } //设置按钮打开监听器接口 publicinterfaceSoftFloorListener{ voidsoftFloor(); } //设置按钮打开监听器接口 publicinterfaceHydropowerListener{ voidhydropower(); }}