概述
自定义View这东西很多哥们比较畏惧,如果你认为他比较难,关键还是缺少实践写得少;如果你认为很简单,那可能是你没有遇到过那些奇葩的效果,需要高等数学和各种算法。当然我想要做的就是让大家觉得很简单,如果你做了一两年Android开发,给你一个效果根本没法下手,会比较尴尬。自定义View是第一个坎,系统架构,数据结构算法,内存优化,NDK后面还会有很多坎,每一个坎都需要花一定的时间。
对于自定义View其实有一些套路,比如onMeasure(),onDarw(),onTouch(),自定义属性,我们需要知道是用来干什么的,剩下就是一些逻辑代码了,其实也很简单。当然后面讲自定义ViewGroup需要看源码,后面的事后面再说,今天这里我们主讲自定义View的一些基础知识。
自定义View方法简介
系统给我们提供了很多控件,比如TextView,ImageView,Button等等,这些其实也可以说是自定义View,只不过这些是Google工程师已经写好,提供给我们用的而已。
我们自己实现一个TextView的效果算做是入门,这期主要介绍几个方法,下期再写逻辑代码:
2.1. onMeasure()方法
对于onMeasure我们不得不说一下测量模式,发现网上很多人写的文章有些许差异。当然测量模式与父View有一定的关系,这里我们先不关注,如果目前实在不懂那需要记住,分别是UNSPECIFIED,EXACTLY,AT_MOST。至于怎么获取怎么用我们下期再说。(后面会分析View的绘制流程源码,会有些许差别)。
2.2. onDarw()方法
主要用来绘制效果,里面会有一个参数那就是canvas画布,利用canvas就可以画各式各样的效果,如:canvas.drawCircle()画圆形,canvas.drawBitmap()画bitmap,我们这里肯定是需要画文字,那就是drawText()画文本。
@Override
protected void onDraw(Canvas canvas) {
// 画圆
canvas.drawCircle();
// 画bitmap
canvas.drawBitmap();
// 画文本
canvas.drawText();
// ......
}
2.3. onTouch()方法
用来处理触摸事件与用户进行交互,比如我早期写过QQ5.0,6.0侧滑效果,字母索引列表效果等等。MotionEvent.ACTION_DOWN(手指按下)、MotionEvent.ACTION_MOVE(手指移动)、ACTION_UP(手指抬起)。当然还有一个比较难以处理的,就是事件分发问题,要看过源码才行,后面再说。
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG,"ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG,"ACTION_UP");
break;
}
return super.onTouchEvent(event);
}
2.3. 自定义属性
自定义属性就是做到配置不写死,比如我在TextView中text配置什么就显示什么,textColor指定什么颜色就显示什么颜色等等,这些都是自定义属性。首先在res下的values目录下新建一个attrs.xml文件,其他名称可以吗?是可以的如attr.xml或者lqbz.xml但是原则上一看attrs就知道是自定义属性。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TextView">
<attr name="wqqtext" format="string"/>
<attr name="wqqtextcolor" format="color"/>
<attr name="wqqtextSize" format="dimension"/>
<attr name="wqqmaxLength" format="integer"/>
<attr name="wqqinputType">
<enum name="number" value="1"></enum>
<enum name="text" value="1"></enum>
<enum name="password" value="1"></enum>
</attr>
</declare-styleable>
</resources>
在布局文件中使用
<com.example.viewday_01.TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:wqqinputType="number"
app:wqqtextcolor="#FF0000"
app:wqqtext="wqq"
app:wqqtextSize="11dp"
/>
代码中获取,我们可以去仿照TextView的源码写
public TextView(Context context) {
this(context,null);
}
public TextView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public TextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 获取TypedArray
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.TextView);
// 获取文本
mText = typedArray.getText(R.styleable.TextView_wqqtext);
// 获取文字颜色
mTextColor = typedArray.getColorStateList(R.styleable.TextView_wqqtextColor);
// 获取文字大小
mTextSize = typedArray.getDimensionPixelSize(R.styleable.TextView_wqqtextSize,mTextSize);
// 回收
typedArray.recycle();
}
万丈高楼平地起,万事开头难。下期我们再来写逻辑代码就算是入了门,以后所有的自定义效果也离不开这几个方法,离不开这些套路。