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
- Android自定义View 之 SwitchButtonView
- Android之自定义View
- android 之自定义View
- Android之自定义View
- Android之自定义View
- Android之自定义View
- Android 之 自定义View
- Android 自定义View 之 自定义View属性
- android自定义view之---组合view
- Android自定义View 之 View的测量
- Android 自定义View之View的绘制
- android自定义View练习之波浪View
- Android自定义view之(刻度尺view)
- android 自定义View之Path
- android之【LinearLayout自定义View】
- android 自定义view之onMeasure
- Android 自定义View之BounceProgressBar
- android开发之自定义View
- Android Studio各种情况下导入library的教程(图解)
- Orace执行计划分析说明
- 2016 中国企业服务峰会:如何让数据更具商业价值
- GPU 加速下的图像视觉
- [Mysql]Host “”is not allowed to connect to this MySQL server——如何设置远程
- Android自定义View 之 SwitchButtonView
- springMVC请求访问静态资源报错javax.servlet.http.HttpServletRequest.getHeader(Ljava/lang/String;)
- hdoj 2041/2042/2043/2044/2046 (递归——斐波那契数列)
- 句柄
- 设计模式:策略模式(Strategy)
- php编码解码json对象
- Android 图片压缩展示 防止使用MediaStore.Images.Media.getBitmap造成的OOM异常
- 常见的几种RuntimeException
- Java 8 新特性:Lambda 表达式之方法引用(Lambda 表达式补充版)——诺诺"涂鸦"记忆