[置顶] 安卓自定义控件初探---仿web验证码的实现

        自定义控件对于安卓进阶来说是一门必不可多少的课程,作为菜鸟的我,也开始学习安卓自定义控件,搞了一上午,勉强写出来了一个demo,但是还是很有收获的。自定义控件给我的感觉就是:这些知识点都是成系统的,缺了一小块知识,就会很迷惑。我将我在探索自定义控件中遇到的一些想法和收获记录下来,希望能和大家切磋一下,共同进步。下面就开始。

       自定义控件必备的基础知识:

自定义控件通常继承View类或者ViewGroup类。ViewGroup通常用来自定义容器,比如FlowLayout用来实现流式布局。
在View类里,可以看见,View类有四个构造函数:
       1,一个参数的构造,用来在java代码里,也就是new一个新的对象
       2,两个参数的构造,用于在布局文件里面配置。这种方式的构造不能实现自定义属性和自定义主题,这些自定义控件的属性和主题来自传入的context的主题和参数。官方解释如下:

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。

       3,三个参数的构造,用于在xml配置,并且可以实现自定义属性。这里有官方解释: This constructor of Viewallows subclasses to use their own base style when they are inflating. 
       4,四个参数的构造,这个需要使用的SDK版本大于21,发现这个构造比三个参数的构造多一个参数: defStyleRes。这个的用法和上一种一样,只不过在三个构造方法的最后一个参数 defStyleAttr为0的时候,会调用此构造,用新增的参数来代表此控件的样式资源。

看完构造函数,我们来看看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已经完成,这个很简单的例子送给大家,下一篇关于自定义控件的介绍,将研究自定义控件的onMeasure方法。

demo下载地址:点击下载demo






你可能感兴趣的:(android,自定义控件)