在开发中很多时候我们会用到自定义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);
    }
}