android View的详解 之 自定义view (三)

来源:互联网 发布:mac散热口在哪 编辑:程序博客网 时间:2024/06/05 15:06
1.1 我们为什么要自定义view?
当系统提供给我们的组件满足不了我们的需求时,为了做出更绚丽的效果,我们自定义view来实现我们的需求;

2.1 我们为自定义view分为四类:
1)view重写onDraw方法
主要实现一些不规则效果,静态或者动态显示不规则图形,不方便通过布局组合方式实现,需要自己支持wrap_content,padding也需要自己处理;
2)继承viewGroup,派生特殊的layout
我们实现自定的布局,除了系统提供的三种布局之外,自己定义一个布局,用来显示几种view组合在一起的布局。这个方法略复杂。需要合适处理wrap_content测量,布局两个过程,
3)继承特点的view(textView)
扩展已有的功能,不需要自己支持wrap_content和padding;
4)几种view组合在一起,不需要处理viewGroup的测量和布局这两个过程;

3.1自定义view时的注意事项;
1)让view支持wrap_content
因为我们在继承view或者viewGroup时,在measure中对wrap_content进行特殊处理,当外部使用wrap_content时候,会达不到我们预期的效果;
如何处理看4.3.1章节
2)让view支持padding
当我们继承view控件时,应在draw方法中对padding进行处理,如果不做处理padding会失效;
继承viewGroup控件时;应该在measure和onlayout中考虑padding和子元素margin带来的影响,
不然导致padding和子元素的margin失效;
3)尽量不要再view中使用handler
因为view本身带有一系类post方法,可以代替handler作用,除非明确的使用handler发送消息;
4)view带有滑动嵌套时,需要处理好滑动冲突。
如果有滑动冲突,会对效果造成影响
5)view有线程和动画需要及时停止;
view变得不可见时,需要停止线程和动画,如果处理不及时,会造成内存泄露;

4.1 我们自定义控件
1)自定义view,重写onDraw方法;并设置宽高;

之后添加padding和margin属性,padding并没有效果。
运行效果:

2)我们将layout_width="match_parent"修改为“wrap_content”,在运行:

运行效果:

发现wrap_content和main_partent运行效果一样;如果我们不对wrap_content进行处理;
wrap_content和main_parent一样;
3)对padding进行处理



运行效果:

我们对padding做出处理padding,wrap_content均生效了;

4.2 自定义属性
在value目录下创建attrs.xml文件,创建xml布局; (布局格式如下:)

在自定义View的构造方法中,解析自定义属性的值并做处理;

布局文件如下:
布局文件中需要注意的是:引入命名空间:
xmlns:apps="http://schemas.android.com/apk/res-auto"

效果展示:

颜色修改成功:
5.1 自定义view 三个构造方法
第一个构造方法:当我们不需要使用xml声明时;
(例如我们在代码中new 一个对象时,走此构造函数)
第二个构造方法:需要在xml中声明,
(当我们引用我们的布局时;)
第三个构造方法:
当我们自定义属性的时候,走第三个构造方法;
系统只针对前两个构造方法做操作;我们通过手动方法实现系统走第三个构造方法;

三个构造方法的参数:
1)Context context:上下文
2)AttributeSet attrs:设置的属性集合
3)int defStyleAttr:当前主题中包含一个style的引用

6.1 onDraw(canvas canvas)中绘制
  mPaint =new Paint(); 
        // 绘制画布背景 
        canvas.drawColor(Color.GRAY); 
        //设置画笔颜色 
        mPaint.setColor(Color.BLUE); 
        //设置画笔为空心     如果将这里改为Style.STROKE  这个图中的实线圆柱体就变成了空心的圆柱体 
        mPaint.setStyle(Paint.Style.STROKE); 
        //绘制直线 
        canvas.drawLine(50, 50, 450, 50, mPaint); 
        //绘制矩形 
        canvas.drawRect(100, 100, 200, 300, mPaint); 
    
        // 画圆 
        canvas.drawCircle(50, 500, 50, mPaint); 
        RectF oval = new RectF(350, 500, 450, 700); 
        // 画椭圆 
        canvas.drawOval(oval, mPaint); 
 
7.1 onMeasure();
修改为支持wrap_content, onMeasure()的完整代码;


阅读全文
1 0