自定义View

来源:互联网 发布:淘宝店铺密码忘了 编辑:程序博客网 时间:2024/05/18 01:47

只有站在设计者的角度上,才可以更好的创建出定义View。

在自定义View时,我们通常会去重写onDraw()方法来绘制View显示的内容,如果该View还要使用wrap_content属性,那么嗨必须重写onMeasue方法。另外,通过自定义attrs属性还可以设置新的属性配置。

View中重要的回调方法:

onFinishInflate():从xml加载组建后回调。

onSizeChanged():组件大小改变的时候回调。

onMeasure():回调该方法来进行测量。

onLayout():回调该方法来确定显示的位置。

onTouchEvent():监听到触摸事件的时候回调。

创建自定一个View并不需要重写所有方法,只重写特定条件下的回调即可。

自定义View的实现方式:

1、对现有的控件进行扩展。

2、通过组合控件实现新的控件。

3、重写View来实现全新的控件。


对现有的控件进行扩展:

在构造方法中完成必要的对象的初始化工作。

@Override  

protected void onDraw(Canvas canvas) {

//实现自己的逻辑
        super.onDraw(canvas);

//实现自己的逻辑

}



通过组合控件实现新的控件

通常需要继承一个合适的ViewGroup,给他添加指定功能的控件。

使用自定义View与系统原生的View的区别就是在声明控件的时候,需要制定完整的包名,而在引用自定义属性的时候,需要使用自定义的xmlns名字。


重写View来实现全新的控件

实现全新的View难点在于绘制控件和实现交互。

通常需要继承View类,重写onDraw方法,onMeasure方法来实现绘图的逻辑。同时通过重写onTouchedEvent等触控事件来实现交互逻辑。


自定义ViewGroup的实现方式:

自定义ViewGroup的目的就是为了对其子View进行管理,为其子View添加显示,响应的规则。

因此,自定义ViewGroup通常需要重写onMeasure方法来对子View尽心测量,重写onLayout方法来确定子View的位置。重写onTouchEvent增加响应事件。

代码模板:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
        }
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
        mlp.height = childCount * mScreenHeight;
        setLayoutParams(mlp);
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != View.GONE) {
                child.layout(l, i * mScreenHeight, r, (i + 1) *mScreenHeight);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        postInvalidate();
        return true;
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            scrollTo(0, mScroller.getCurrY());
            postInvalidate();
        }
    }







0 0