Android自定义View 之 SwitchButtonView
2016-04-19 14:29
453 查看
转载请注明原作者:/article/11247554.html
Demo :APK托管地址
通过继承view实现一个SwitchButtonView的控件,并通过onTuch事件实现精确onClick效果,下面是实现效果图。
首先写一个SwitchButtonView继承view并实现OnTouchListener方法。
在values 文件夹下创建一个attrs资源文件并给自定义View配置相关属性,以便在布局中动态传入这些属性值。
并在SwitchButtonView(Context context, AttributeSet attrs, int defStyleAttr)方法中引用这些属性做一些初始化操作。为了达到通用效果defValue值设置相应合适的参数。
参数获得后在初始化各种Paint为onDraw做相应准备。
在onMeasure方法中设置view的大小以便onDraw绘制出控件,为什么加10?这是为了达到绘制边缘完全显示出效果,在onDraw方法中我会将原点平移到(5,5)。
最核心的方法在onDraw中实现。代码如下:
为了达到精确点击某一块的onCick方法,通过ontouch获得坐标判断点击区域实现,就不做过多讲解了,代码如下:
下面是简单的使用方法:
下载链接:源码
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); } });
下载链接:源码
相关文章推荐
- Android版仿ios可以上下拉的ScrollView
- android keytool 不是内部命令或外部命令在 (win7下不能用的解决方法)
- Android 获取外置SD卡路径
- Android_GPS
- Android 和HTml交互
- Android Studio Error:Connection timed out: connect.解决方案
- Android ANR 分析
- 《ArcGIS Runtime SDK for Android开发笔记》——问题集:Error:Error: File path too long on Windows, keep below 240 characters
- Andorid自定义attr的各种坑
- Android Studio: 对gradle的理解
- android 系统获取通话状态的方法
- android延时执行
- 浏览器判断是否安装了ios/android客户端程序
- ReDex —— Facebook 的 Android 字节码优化工具
- android的 root权限
- android设置字体工具类(需要自己先下载ttf文件)
- Android基础控件 - Spinner
- Android输入法弹出时覆盖输入框问题的解决方法
- 图片裁剪Imageview
- Android的Drawable