android自定义控件笔记

来源:互联网 发布:node.js是前端还是后端 编辑:程序博客网 时间:2024/05/21 06:42

android系统提供的控件有时候满足不了我们的需求 ,这个时候我们就可以通过自定义控件来实现自己想要的控件样式和功能,下面把自己记录的自定义控件的一些笔记拿出来给大家参考:

自定义控件有组合自定义控件和单个的自定义控件,组合自定义控件就是一个容器里面包含一个TextView和一个EditText,容器可以是LinearLayout或者RelativeLayout,或者自己自定义的,一般就是继承ViewGroup,在代码中根据自己容器的不同来继承:

比如你选择组合容器是LinearLayout,那么代码中继承LinearLayout,如果是RelativeLayout那就继承RelativeLayout,如果是自己来自定义那就直接继承ViewGroup。

比如这里我直接继承ViewGroup,

<span style="font-size:14px;">public class FlowLayout extends ViewGroup</span>
继承之后,我们就需要实现构造方法,一般一个参数的构造方法是当你在代码中直接new的时候调用

<span style="font-size:14px;">public FlowLayout(Context context) {super.(context);}</span>
两个参数的构造方法,这个是在xml创建但是没有指定style的时候被调用
<span style="font-size:14px;">public FlowLayout(Context context, AttributeSet attrs) </span>
三个参数的构造方法是在xml创建,并且指定了style的时候被调用

public FlowLayout(Context context, AttributeSet attrs, int defStyle)
一般我们都在第二个构造方法中获取xml文件上定义的属性
具体的大家可以看我的另外一篇文章,里面有说明怎么通过xml来自定义控件属性:

http://blog.csdn.net/fanxl10/article/details/41863217

今天要说的是自定义控件的onMeasure和onLayout方法的应用,

控件一般需要进行绘制,那么onMeasure方法就是控件绘制的时候进行控件测量的方法,测量每个控件的宽高

测量方法有三种,分别是AT_MOST 一般是wrap_contetn的时候进行的测量; 

EXACITY 一般设定了固定的值,如100dp 或者是match_parent时候测量; 

另外一个是UNSPECIFIED 子View想要多大就多少,这个很少见;

然后我们就可以获取模式和尺寸

int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);  //获取控件宽度尺寸int modeWidth = MeasureSpec.getMode(heightMeasureSpec); //获取控件宽度模式int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); //获取控件高度尺寸int modeHeight = MeasureSpec.getMode(heightMeasureSpec); //获取控件高度模式

如果是EXACITY的,那么上面就已经获取到了尺寸,我们就可以直接使用,如果AT_MOST,那么我们还需要自己进行计算;

如果里面有子view的话,我们就需要根据子view的宽高设置父控件;

//Wrap_content 这个就需要自己去计算, 如果是EXACITY,上面的方法就可以获取到int width = 0;int height = 0;
}}<span style="white-space:pre"></span><pre name="code" class="java">//得到内部元素的个数int count = getChildCount();for (int i = 0; i < count; i++) {<span style="white-space:pre"></span>View child = getChildAt(i);//测量子View的宽高measureChild(child, widthMeasureSpec, heightMeasureSpec);MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
<span style="white-space:pre"></span>width += childWidth;
<span style="white-space:pre"></span>height = childHeight;
}

获取到宽高之后,我们就根据获取到的模式进行判断,最终把宽高赋值给控件:

setMeasuredDimension(modeWidth==MeasureSpec.AT_MOST?width+getPaddingLeft()+getPaddingRight():sizeWidth, modeHeight==MeasureSpec.AT_MOST?height+getPaddingTop()+getPaddingBottom():sizeHeight);

最后就是在onLayout里面进行布局








0 0