网站开发的主要工作,游戏网站开发什么意思,广州建站模板厂家,昆明seo关键词首先了解view的绘制流程#xff1a; 所以onmeasure ---测量view
onlayout---确定view大小----》所以继承ViewGroup必须要重写onlayout#xff0c;确定子view
而onDraw----是继承view时候需要操作的。
所以#xff1a;自定义ViewGroup一般是利用现有的组件根据特定的布局…首先了解view的绘制流程 所以onmeasure ---测量view
onlayout---确定view大小----》所以继承ViewGroup必须要重写onlayout确定子view
而onDraw----是继承view时候需要操作的。
所以自定义ViewGroup一般是利用现有的组件根据特定的布局方式来组成新的组件。 自定义View一般是没有现成的view 序列化大概有这个意思不一定对。 自定义序列化 IOT 协议比如物联网蓝牙传递的数据 串口 协议
onmeasure的测量 是先从子布局开始还是先从父布局开始的
----根据算法来控制的比如view pageer就是父布局开始
MeasureSpec是什么
public static class MeasureSpec {private static final int MODE_SHIFT 30;private static final int MODE_MASK 0x3 MODE_SHIFT;/** hide */IntDef({UNSPECIFIED, EXACTLY, AT_MOST})Retention(RetentionPolicy.SOURCE)public interface MeasureSpecMode {}----是view里面的一个类---我们知道int 是32位
------上面代码里的30就是高两位是00后面30位---》所以这组成里MeasureSpec
-------高两位表示UNSPECIFIEDEXACTLYAT_MOST
关于getChildMeasureSpec(int spec, int padding, int childDimension)算法
第一个参数父亲给的
第二个参数父亲的
第三个参数孩子需要的
-----》根据UNSPECIFIEDEXACTLYAT_MOST来计算 public static int getChildMeasureSpec(int spec, int padding, int childDimension) {int specMode MeasureSpec.getMode(spec);int specSize MeasureSpec.getSize(spec);int size Math.max(0, specSize - padding);int resultSize 0;int resultMode 0;switch (specMode) {// Parent has imposed an exact size on uscase MeasureSpec.EXACTLY:if (childDimension 0) {resultSize childDimension;resultMode MeasureSpec.EXACTLY;} else if (childDimension LayoutParams.MATCH_PARENT) {// Child wants to be our size. So be it.resultSize size;resultMode MeasureSpec.EXACTLY;} else if (childDimension LayoutParams.WRAP_CONTENT) {// Child wants to determine its own size. It cant be// bigger than us.resultSize size;resultMode MeasureSpec.AT_MOST;}break;// Parent has imposed a maximum size on uscase MeasureSpec.AT_MOST:if (childDimension 0) {// Child wants a specific size... so be itresultSize childDimension;resultMode MeasureSpec.EXACTLY;} else if (childDimension LayoutParams.MATCH_PARENT) {// Child wants to be our size, but our size is not fixed.// Constrain child to not be bigger than us.resultSize size;resultMode MeasureSpec.AT_MOST;} else if (childDimension LayoutParams.WRAP_CONTENT) {// Child wants to determine its own size. It cant be// bigger than us.resultSize size;resultMode MeasureSpec.AT_MOST;}break;// Parent asked to see how big we want to becase MeasureSpec.UNSPECIFIED:if (childDimension 0) {// Child wants a specific size... let them have itresultSize childDimension;resultMode MeasureSpec.EXACTLY;} else if (childDimension LayoutParams.MATCH_PARENT) {// Child wants to be our size... find out how big it should// beresultSize View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;resultMode MeasureSpec.UNSPECIFIED;} else if (childDimension LayoutParams.WRAP_CONTENT) {// Child wants to determine its own size.... find out how// big it should beresultSize View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;resultMode MeasureSpec.UNSPECIFIED;}break;}//noinspection ResourceTypereturn MeasureSpec.makeMeasureSpec(resultSize, resultMode);}
下面是一个流式布局的例子 * desc : 官方FlexboxLayout 流式布局*/
class FlowLayout(context: Context) : ViewGroup(context) {private val mHorizontalSpacing dp2px(16f) //每个item横向间距private val mVerticalSpacing dp2px(8f) //每个item竖向间距private var allLines:MutableListMutableListView ArrayListMutableListView() //记录所有的行一行一行保存用于layoutvar lineHeights:ArrayListInt ArrayList()//记录每一行的行高用于layoutconstructor(context: Context,attrs:AttributeSet):this(context){// 在这里处理从 XML 布局 --序列化格式--建值对}constructor(context: Context, attrs: AttributeSet, defStyle: Int) : this(context, attrs) {// 在这里处理从 XML 布局文件中传入的属性和样式}//初始化因为是onMeasure递归的方式所以要放在onMeasureprivate fun clearMeasureParams(){
// allLines ArrayListMutableListView()
// lineHeights ArrayList()allLines.clear()lineHeights.clear()}override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {clearMeasureParams()// 内存抖动
// super.onMeasure(widthMeasureSpec, heightMeasureSpec)//先度量孩子val childCount childCount//ViewGroup解析父控件给我的宽高val selfWidth MeasureSpec.getSize(widthMeasureSpec)val selfHeight MeasureSpec.getSize(heightMeasureSpec)//measure过程中 子view要求的父viewgroup的宽高var parentNeededWidth 0;var parentNeededHeight 0;val linView ArrayListView()var lineWidthUsed 0 //记录这一行的以及使用了多宽的sizevar lineHeight 0 //一行的杭高for (i in 0 until childCount){val childview getChildAt(i)val childlayoutParams childview.layoutParamsif (childview.visibility ! GONE) {val childWidthMeasureSpec getChildMeasureSpec(widthMeasureSpec,paddingLeft paddingRight,childlayoutParams.width)val childHeightMeasureSpec1 getChildMeasureSpec(heightMeasureSpec,paddingTop paddingBottom,childlayoutParams.height)childview.measure(childWidthMeasureSpec, childHeightMeasureSpec1)//获取子view的度量高度val childMeasureWidth childview.measuredWidthval childmeasuredHeight childview.measuredHeightlinView.add(childview)//是否药换行if (childMeasureWidth lineWidthUsed mHorizontalSpacing selfWidth) {//换行判断当前行所需要的宽和高所以要记录下来allLines.add(linView)lineHeights.add(lineHeight) //行高。。这个if语句会缺少最后一行parentNeededHeight parentNeededHeight lineHeight mVerticalSpacingparentNeededWidth Math.max(parentNeededWidth, lineWidthUsed mHorizontalSpacing)linView.clear()lineWidthUsed 0lineHeight 0}//每行自己的宽高lineWidthUsed lineWidthUsed childMeasureWidth mHorizontalSpacinglineHeight Math.max(lineHeight, childmeasuredHeight)//最后一行if (i childCount - 1) {allLines.add(linView)lineHeights.add(lineHeight)parentNeededHeight parentNeededHeight lineHeight mVerticalSpacingparentNeededWidth Math.max(parentNeededWidth, lineWidthUsed mHorizontalSpacing)}}}//度量自己//根据子view的度量结果来重新度量自己的viewGroup//作为一个viewgroup他自己也是个view他的大小也需要根据他的父亲提供的宽高来度量var withmode: Int MeasureSpec.getMode(widthMeasureSpec)var heightmode: Int MeasureSpec.getMode(heightMeasureSpec)//确切的值 EXACTLYval realWidth if(withmode MeasureSpec.EXACTLY) selfWidth else parentNeededWidthval realHeight if(heightmode MeasureSpec.EXACTLY) selfHeight else parentNeededWidthsetMeasuredDimension(realWidth,realHeight)}override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {val lineCount allLines.sizevar curl paddingLeft //左边届var curT paddingTop //上边界for(i in 0 until lineCount){val Lineviews allLines.get(i)val lineHeight lineHeights.get(i)for (j in 0 until Lineviews.size){//其中一行val view Lineviews.get(j)//这一行的view//计算边界val left curl //左边届val top curT //上边界val right leftmeasuredWidth//左边届val botton top measuredHeight //上边界view.layout(left,top,right,botton)curl rightmHorizontalSpacing//下一个左边}curT curT lineHeightmVerticalSpacing //下一个topcurl paddingLeft //每一个新的行要重制左边届}// view.layout(left,top,right,bottom)}
}