Android自定义View 之 SwitchButtonView

来源:互联网 发布:战舰世界鞍山数据 编辑:程序博客网 时间:2024/06/06 05:40

转载请注明原作者:http://blog.csdn.net/hnfc123/article/details/51190248

Demo :APK托管地址

  这个控件主要解决多个自定义button,textview或者imageview切换繁琐的问题。通过这个控件可以简单快速的实现相应功能。监听切换也非常简单。

通过继承view实现一个SwitchButtonView的控件,并通过onTuch事件实现精确onClick效果,下面是实现效果图。

这里写图片描述

  • 首先写一个SwitchButtonView继承view并实现OnTouchListener方法。
public class SwitchButtonView extends View implements OnTouchListener{
  • 在values 文件夹下创建一个attrs资源文件并给自定义View配置相关属性,以便在布局中动态传入这些属性值。
 <declare-styleable name="labelSwitch">        <attr name="switchwidth" format="dimension" />         <attr name="switchheight" format="dimension" />          <attr name="switchlableNames" format="string" />        <attr name="switchbgcolor" format="color" />        <attr name="switchlovalcolor" format="color" />        <attr name="norswitchTextColor" format="color" />        <attr name="nelswitchTextColor" format="color" />          <attr name="switchTextSize" format="dimension" />          <attr name="StrokeWidth" format="integer" />     </declare-styleable>

并在SwitchButtonView(Context context, AttributeSet attrs, int defStyleAttr)方法中引用这些属性做一些初始化操作。为了达到通用效果defValue值设置相应合适的参数。

参数获得后在初始化各种Paint为onDraw做相应准备。

private void init(){        bgPaint = new Paint();        bgPaint.setAntiAlias(true);        bgPaint.setColor(switchbgcolor);        cPaint = new Paint();        //设置抗锯齿        cPaint.setAntiAlias(true);        //设置空心        cPaint.setStyle(Paint.Style.STROKE);         //设置画出的线的 粗细程度          cPaint.setStrokeWidth(StrokeWidth);          cPaint.setColor(switchlovalcolor);        //选中矩形画笔        scPaint = new Paint();        scPaint.setAntiAlias(true);        scPaint.setColor(switchlovalcolor);        rtPaint = new Paint();        rtPaint.setAntiAlias(true);        rtPaint.setTextSize(textSzie);        rtPaint.setColor(norswitchTextColor);        wtPaint = new Paint();        wtPaint.setAntiAlias(true);        wtPaint.setTextSize(textSzie);        wtPaint.setColor(nelswitchTextColor);    }
  • 在onMeasure方法中设置view的大小以便onDraw绘制出控件,为什么加10?这是为了达到绘制边缘完全显示出效果,在onDraw方法中我会将原点平移到(5,5)。
@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        // TODO Auto-generated method stub        //件尺寸增加10目的是让画最外层矩形时粗细设置可见        setMeasuredDimension(measuredWidth+10, measuredHeight+10);    }
  • 最核心的方法在onDraw中实现。代码如下:
@Override    protected void onDraw(Canvas canvas) {        //将坐标原点移到(5,5)        canvas.translate(5, 5);         // 设置个矩形,扫描测量           RectF oval = new RectF(0, 0, measuredWidth, measuredHeight);         //画背景颜色         canvas.drawRoundRect(oval, measuredHeight/2, measuredHeight/2,bgPaint);//第二个参数是x半径,第三个参数是y半径           //画圆角矩形         canvas.drawRoundRect(oval, measuredHeight/2, measuredHeight/2,cPaint);         //根据数据动态计算画直线i=1开始画线         for (int i = 1; i < lable.size(); i++) {             float X = measuredWidth/lable.size()*i;            //画直线             canvas.drawLine(X, 0, X, measuredHeight, cPaint);        }         //特殊化最后一个和第一个         if (clickIndex==0) {            //初始化选中lable             oval.set(0, 0, measuredWidth/lable.size(), measuredHeight);             canvas.drawRoundRect(oval, measuredHeight/2, measuredHeight/2,scPaint);             oval.set(measuredHeight/2, 0, measuredWidth/lable.size(), measuredHeight);             //画矩形             canvas.drawRoundRect(oval, 0, 0,scPaint);        }else if (clickIndex==lable.size()-1) {             oval.set(measuredWidth/lable.size()*clickIndex, 0, measuredWidth, measuredHeight);             canvas.drawRoundRect(oval, measuredHeight/2, measuredHeight/2,scPaint);             oval.set(measuredWidth/lable.size()*clickIndex, 0, measuredWidth/lable.size()*clickIndex + measuredHeight/2, measuredHeight);             //画矩形             canvas.drawRoundRect(oval, 0, 0,scPaint);        }else {             oval.set(measuredWidth/lable.size()*clickIndex, 0,measuredWidth/lable.size()*(clickIndex+1), measuredHeight);             canvas.drawRoundRect(oval, 0, 0,scPaint);         }        //动态画文字        for (int i = 0; i < lable.size(); i++) {            //获得画笔TextBounds以便获取字体宽度和高度            rtPaint.getTextBounds(lable.get(i), 0, lable.get(i).length(), bounds);            float startX = (float)measuredWidth/lable.size()*i + ((float)measuredWidth/lable.size() - (float)bounds.width())/2;            float startY = (float)measuredHeight/2 + (float)bounds.height()/3;            if (i==clickIndex) {                canvas.drawText(lable.get(i), startX, startY, wtPaint);            }else {                canvas.drawText(lable.get(i), startX, startY, rtPaint);            }        }    }

为了达到精确点击某一块的onCick方法,通过ontouch获得坐标判断点击区域实现,就不做过多讲解了,代码如下:

/**     * 通过onTouch实现onClick效果     */    @SuppressLint("NewApi")    @Override    public boolean onTouch(View arg0, MotionEvent arg1) {        // TODO Auto-generated method stub        switch (arg1.getAction()) {        case MotionEvent.ACTION_DOWN://按下            int tempX = (int) (arg1.getRawX()-arg0.getX());            clickIndex = tempX/((measuredWidth+10)/lable.size());            //通知onDraw重新绘制            invalidate();            try {                //接口回调                switchOnClickListener.onClick(arg0,clickIndex,lable.get(clickIndex));            } catch (Exception e) {                //不打印log,这里接口回调会报空指针,属正常            }            break;        case MotionEvent.ACTION_UP://抬起//          Log.i("", "抬起");//          //接口回调//          switchOnClickListener.onClick(arg0,clickIndex,lable.get(clickIndex));            break;        default:            break;        }        return true;    }

下面是简单的使用方法:

 <com.example.SwitchButtonView        android:id="@+id/switchview"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:layout_marginTop="30dp"        app:StrokeWidth="5"        app:nelswitchTextColor="#ffffff"        app:norswitchTextColor="#ffffff"        app:switchTextSize="17sp"        app:switchbgcolor="#e0e0e0"        app:switchheight="40dp"        app:switchlableNames="全部,未服务,已服务,无服务"        app:switchlovalcolor="#ae0000"        app:switchwidth="250dp" /> 
SwitchButtonView view = (SwitchButtonView)findViewById(R.id.switchview);        view.setSwitchOnClickListener(new SwitchOnClickListener() {            @Override            public void onClick(View view, int index, String buttonName) {                // TODO Auto-generated method stub                String string = "index:" + index + "---buttonName:" + buttonName;                textview.append("\n");                textview.append(string);            }        });

下载链接:源码

0 0
原创粉丝点击