3.4、视图view_自定义控件

源码地址:https://github.com/ldy1993/ToolforAS.git

我这里很简单学习自定义view,可以借助百度和android,api弄懂别人写什么即可。

************************************************************************************************************************

深入的话可以看下面链接,我觉得他写的好好,有时间我也自己写一份关于view的专栏。

https://blog.csdn.net/lfdfhl/article/details/51671038

*********************************************************************************************************************************

 

首先创建一个SuspensionView类,继承View

有时我们会发现as的android.view.View不能自动导入,那是因为setting中自动导包做了限制,本来取消就可以,但是我觉得他既然在那里默认设置了,应该是有用的。所以我没有去掉,手动去import android.view.View;

 

 

然后使用快捷键alt+insert实现构造方法,各种有参和无参构造方法,我们先不理参数的具体意义,我们后面在讲。先看自定义View的三个重要的步骤:measure,layout,draw。我们分别重写上述方法

onMeasure

首先分析measure测量,onMeasure主要的工作是测量子view的本身的大小,如下

 onMeasure可以自动解析xml,或者在重写onMeasure使用java,例如setMeasuredDimension(width, height);

重新定义测量view的大小,如下


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            setMeasuredDimension(100, 22);
    }

其中widthMeasureSpec和heightMeasureSpec属于MeasureSpec,他是一种MeasureSpec通常翻译为”测量规格”,它是一个32位的int数据. 其中高2位代表SpecMode即某种测量模式,低30位为SpecSize代表在该模式下的规格大小. 

1 MeasureSpec封装了父布局传递给子View的布局要求。 
2 MeasureSpec可以表示宽和高 
3 MeasureSpec由size和mode组成

可以通过如下方式分别获取这两个值:

获取SpecSize

int specSize = MeasureSpec.getSize(measureSpec)

获取specMode

int specMode = MeasureSpec.getMode(measureSpec)

当然,也可以通过这两个值生成新的MeasureSpec

int measureSpec=MeasureSpec.makeMeasureSpec(size, mode);

 

SpecMode一共有三种: 


MeasureSpec.EXACTLY 
官方文档的描述:The parent has determined an exact size for the child. The child is going to be given those bounds regardless of how big it wants to be.
MeasureSpec.EXACTLY模式表示:父容器已经检测出子View所需要的精确大小。 在该模式下,View的测量大小即SpecSize。

MeasureSpec.AT_MOST 
官方文档的描述:The child can be as large as it wants up to the specified size.
MeasureSpec.AT_MOST模式表示:父容器未能检测出子View所需要的精确大小,但是指定了一个可用大小即specSize 
在该模式下,View的测量大小不能超过SpecSize。

MeasureSpec.UNSPECIFIED 
官方文档的描述:The parent has not imposed any constraint on the child. It can be whatever size it wants.
父容器不对子View的大小做限制.

MeasureSpec.UNSPECIFIED这种模式一般用作Android系统内部,或者ListView和ScrollView等滑动控件,

SpecSize即为控件的大小。

重新onMeasure我们可以获取宽高的MeasureSpec,然后对控件本身大小重新做修改,通常可以用于控件不断重绘制过程不断改变其大小。或者为绘制或者布局提供长宽的数据参考。

onLayout

onLayout()方法用于确定子View的位置,重写onLayout()方法,我们可以重新确认子View的位置

onLayout有五个参数,l,t是代表一个子view左上角的点,r,b是代表右下角的点。change代表该子view是否改变位置。

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        Log.e(TAG, "onLayout: " +left+";;"+top+";;"+right+";;"+bottom);
        super.onLayout(changed, left, top, right, bottom);
    }

 

layout()方法用于View确定自己本身在其父View的位置 ,调用了这个方法后会自动回调onLayout

onDraw

ondraw用于在子View绘制图案。

canvas,画布,在上面调用drawCircle或者line去画圆或者画线。还有很多形状可以在用时面向搜索引擎编程。

mpaint,画笔,可以决定画出来的颜色和画笔类型。

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mpaint.setColor(Color.RED);
        mpaint.setStyle(Paint.Style.FILL_AND_STROKE);
//        canvas.drawLine(10,100,10,100,mpaint);
        canvas.drawCircle(l,t,20,mpaint);
        cv=canvas;
    }

以一个跟随小球为例。在onTouch中去获取触摸点的坐标,然后更新ui,回调onDraw,于是重新改变小球位置

 @Override
    public boolean onTouchEvent(MotionEvent event) {
    Log.e(TAG, "event: " +event.getX()+";;"+event.getY());
    Log.e(TAG, "event: " +event.getX()+";;"+event.getY());
     l=(int)event.getX();
     t=(int)event.getY();
    //更新ui
    invalidate();
        return true;
    }

 

 

 

 

下一节

3.5、创建listview并通过Adapter注入数据

https://blog.csdn.net/u013636987/article/details/101988916

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值