自定义控件对于安卓进阶来说是一门必不可多少的课程,作为菜鸟的我,也开始学习安卓自定义控件,搞了一上午,勉强写出来了一个demo,但是还是很有收获的。自定义控件给我的感觉就是:这些知识点都是成系统的,缺了一小块知识,就会很迷惑。我将我在探索自定义控件中遇到的一些想法和收获记录下来,希望能和大家切磋一下,共同进步。下面就开始。
Constructor that is called when inflating a view from XML. This is called when a view is being constructed froman XML file, supplying attributes that were specified in the XML file. This version uses a default style of 0, so theonly attribute values applied are those in the Context's Theme and the given AttributeSet。
看完构造函数,我们来看看onDraw方法。在View里面发现onDraw方法是空实现,通过方法注释:Implement this to do your drawing.可以看出这个方法就是为View的子类提供的,而自定义控件就是View的子类,所以这个方法是很重要的。它可以根据我们自己的需要绘制画面。由此可见,这是自定义控件的重头戏。这里面通过传入参数Canvas来提供一块画布,让我们“随心所欲”的绘制我们想要绘制的画面。
还有一个比较重要的方法就是:onMeasure,按照官方解释:此方法是用来提供测量控件和内容准确而高效的方法,也是需要子类来重写的。按照这个解释,就是提供一种方法,用来测量此控件和控件里面内容的宽和高,以使画面能够准确的绘制。
以上的知识是学习自定义控件最基础的知识,如果没有理解,可以通过查看源码或者百度来了解,如果发现我写的有错误的话,欢迎留言。
接下来,用上知识来完成今天第一个demo。这个demo通过自定义验证码的大小和颜色来学会如果定义和获取自定义属性,然后再代码中获取这些自定义属性,在onDraw方法里面完成绘制,同时响应点击事件,点击以后完成随机验证码的更换。
1.首先在res/values/文件夹下新建attr文件,来自定义属性:
<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="customeview"> <attr name="myTextColor" format="color"></attr> <attr name="myTextSize" format="dimension"></attr> </declare-styleable> </resources></span>当然我们可以自定义其他的属性,比如说验证码的背景色,字体是否黑体等。关于自定义属性的详细内容,大家可以百度一下:主要是 format的参数的取值。
2,在布局文件里面引入自定义控件
<com.example.custometextview.view.CustomeTextView android:layout_width="200dp" android:layout_height="100dp" customview:myTextColor="#F00" customview:myTextSize="20sp" />可以看见:在布局文件中我们使用到了刚才定义的属性,并且前面加上了一个命名空间:customview,这个命名空间是提前定义的
xmlns:customview="http://schemas.android.com/apk/res/com.example.custometextview"如果要加入自己的属性,就要在xml前面加入此命名空间,只不过把 com.example.custometextview 换成自己的包名,不然在代码中找不到自己自定义的属性。
3,在代码里面找到这些属性和值。通过以上必备知识的介绍,显然我们要在三个参数的构造里面得到这些属性和值。
TypedArray typedArray= context.getTheme().obtainStyledAttributes(attrs, R.styleable.customeview, defStyleAttr,0); for(int i=0;i<typedArray.getIndexCount();i++) { //得到对应下标的属性名称 int attr= typedArray.getIndex(i); switch (attr) { case R.styleable.customeview_myTextColor: myTextColor= typedArray.getInt(attr,Color.RED); break; case R.styleable.customeview_myTextSize: //将sp转化为px myTextSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,14,getResources().getDisplayMetrics())); break; default: break; } } //使用完以后要回收 typedArray.recycle();这里出现了一个新的API, TypedArray,通过eclise的源码定位功能我们发现,这个类是一个包含属性值的数组。这样我们就知道上面代码的含义:遍历此对象,得到我们自定义属性的值。
4,在onDraw方法里面完成绘制,由第三部得到属性值,我们就可以绘制了。在ondraw方法我们可以绘制我们想要的,在此,我们想要绘制一些验证码(4位随机数)和若干条干扰线,而这个在javase提供的Canvas和paint类很容易就可以实现。ondraw代码如下:
paint.setTextSize(myTextSize); paint.setColor(Color.YELLOW); canvas.drawRect(0,0,getMeasuredWidth(), getMeasuredHeight(), paint); paint.setColor(myTextColor); canvas.drawText(myText,getWidth()/2-bound.width()/2, getHeight()/2+bound.height()/2, paint); paint.setColor(Color.GREEN); //画干扰线 for(int i=0;i<10;i++) { canvas.drawLine(0, random.nextInt(getHeight()), getWidth(), random.nextInt(getHeight()), paint); }5,完成点击切换,这对于很多人来说十分简单,就是设置监听器,然后再onClick方法里面响应点击事件,重绘画面。
this.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { myText = getRandomNum(); postInvalidate(); } });
demo下载地址:点击下载demo