在开发中很多时候我们会用到自定义View,在面试中也是不可或缺的问题。今天我们来小小说一下有关View的知识。
首先我们我们需要了解一下我们在自定义view的时候我们需要了解的一些方法。
实现步骤:
1、继承View类或者其子类
2、复写View 中的一些函数
3、给自定义的View类增加属性
4、在layout中导入自定义控件
5、响应用户事件
6、定义回调函数(根据自己的需要进行选择)
我们还需要知道一些我们需要复写的方法:
onDraw()
view中onDraw是个空函数,也就是说具体视图都要覆写该函数来实现自己的绘制,对于ViewGroup则不需要实现该函数,因为作为容器是没有内容的,但必须实现dispatchDraw()函数告诉子view绘制自己。
onLayout()
主要是为ViewGroup类型布局子视图用的,在view中这个函数是空函数。
onMeasure()
用于计算视图大小,即长和宽,并通过setMeasuredDimension(width,height)保存计算结果。
onTouchEvent()
定义触屏事件来响应。
不常用的一些方法:
onKeyDown()当按下某个键盘时
onKeyUp()当松开某个键盘时
onTrackballEvent()当发生轨迹球事件时
onSizeChange()当该组件的大小被改变的时候
onFinishInflate()回调方法,当应用从xml加载该组件并用它来构建界面之后调用的方法
onWindowFocusChanged(boolean)该组件得到,失去焦点
onAttachedToWindow()当把该组件放入到某个窗口时
onDetachedFromWindow()当把该组件从某个窗口上分离时触发的方法
自定义控件的三种方式:
1、继承已有控件
当要实现的控件和以后的控件在很多方面比较类似,通过对已有控件的扩展来满足需求。
2、继承一个布局文件
一般用于自定义组合控件,在构造函数中通过inflter和addView()方法加载自定义控件的布局文件形成图形界面(不需要onDraw方法)
3、继承View
通过onDraw方法来绘制出组件界面
例:自定义随手指移动的小球
在res/values目录下简历attrs.xml文件建立一些属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="myView">
<attr name="TextView" format="color"/>
</declare-styleable>
</resources>
public class MyView extends View {
Paint p=new Paint();
public float currentX=50;
public float currentY=50;
public int textColor;
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray arry=context.obtainStyledAttributes(attrs,R.styleable.myView);
textColor=arry.getColor(R.styleable.myView_TextView, Color.BLACK);
arry.recycle();
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/**
* 画一个蓝色图形
*/
p.setColor(Color.BLUE);
canvas.drawCircle(currentX,currentY,30,p);
p.setColor(textColor);
canvas.drawText("",currentX-30,currentY-30,p);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
currentX=event.getX();
currentY=event.getY();
invalidate();//重新绘制图形
return true;
}
}
layout布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http:///apk/res/android"
xmlns:tools="http:///tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<zhiyuan.view.MyView
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}