學(xué)習(xí)筆記,整理中
摘要
面
1、layoutparams:xml的屬性轉(zhuǎn)換為java用的格式
2、面必問:measurespec
------------------------------------
主要講 自定義viewgroup,viewpager??
1、所有的xml解析 都在 layoutinflater里面
2、自定義view至少3個(gè)構(gòu)造函數(shù),java new view調(diào)用;xml 反射調(diào)用;不同主題調(diào)用;自定義屬性用(這個(gè)很少用)
4、source insite
5、jianshu.com/p/0723ff4123e1 flexboxlayout 流式布局
----------------------------------
實(shí)現(xiàn)UI: 自定義VIew
java 語言
自定義View android 基礎(chǔ)
自定義View 包含什么?
布局: onlayout onmeausre/ Layout:viewGroup
顯示: onDraw? ? ? ? ? :view: canvas paint matrix clip rect animation path(貝塞爾) line? text繪制
? ? ? frameWork:
交互: onTouchEvent? ? :組合的viewGroup
大量的實(shí)戰(zhàn),實(shí)踐/
jett:xml解析原理,view層次結(jié)構(gòu),插件化換膚
2000平
序列化
自定義序列化: IOT
協(xié)議
物聯(lián)網(wǎng):藍(lán)牙:傳遞的數(shù)據(jù) 串口 協(xié)議:
子
自己? ;viewPager
都可以:算法
先孩子再自己
android:layout_width="wrap_content"? -》xxx dp? dip
? ? ? ? ? ? ? ? android:layout_height="wrap_content"
很多知識(shí):算法
MeasureSpec :
size 值
? 0~10000
? int 32:
? 30
int? 11000000000000000000000
mode:高兩位:UNSPECIFIED, EXACTLY, AT_MOST
01 00 11
算法是怎樣的?
SDK一個(gè)包:嚴(yán)謹(jǐn)性,可拓展性
內(nèi)容







----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public class FlowLayoutextends ViewGroup {
private static final StringTAG ="FlowLayout";
? ? private int mHorizontalSpacing =dp2px(16); //每個(gè)item橫向間距
? ? private int mVerticalSpacing =dp2px(8); //每個(gè)item橫向間距
? ? private List>allLines =new ArrayList<>(); // 記錄所有的行,一行一行的存儲(chǔ),用于layout
? ? ListlineHeights =new ArrayList<>(); // 記錄每一行的行高,用于layout
? ? public FlowLayout(Context context) {
super(context);
//? ? ? ? initMeasureParams();
? ? }
//反射
? ? public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
//? ? ? ? initMeasureParams();
? ? }
//主題style
? ? public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//? ? ? ? initMeasureParams();
? ? }
//四個(gè)參數(shù) 自定義屬性
? ? private void clearMeasureParams() {
allLines.clear();
? ? ? ? lineHeights.clear();
? ? }
//度量
? ? @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
clearMeasureParams();//內(nèi)存 抖動(dòng)
? ? ? ? //先度量孩子
? ? ? ? int childCount = getChildCount();
? ? ? ? int paddingLeft = getPaddingLeft();
? ? ? ? int paddingRight = getPaddingRight();
? ? ? ? int paddingTop = getPaddingTop();
? ? ? ? int paddingBottom = getPaddingBottom();
? ? ? ? int selfWidth = MeasureSpec.getSize(widthMeasureSpec);? //ViewGroup解析的父親給我的寬度
? ? ? ? int selfHeight = MeasureSpec.getSize(heightMeasureSpec); // ViewGroup解析的父親給我的高度
? ? ? ? List lineViews =new ArrayList<>(); //保存一行中的所有的view
? ? ? ? int lineWidthUsed =0; //記錄這行已經(jīng)使用了多寬的size
? ? ? ? int lineHeight =0; // 一行的行高
? ? ? ? int parentNeededWidth =0;? // measure過程中,子View要求的父ViewGroup的寬
? ? ? ? int parentNeededHeight =0; // measure過程中,子View要求的父ViewGroup的高
? ? ? ? for (int i =0; i < childCount; i++) {
View childView = getChildAt(i);
? ? ? ? ? ? LayoutParams childLP = childView.getLayoutParams();
? ? ? ? ? ? if (childView.getVisibility() != View.GONE) {
//將layoutParams轉(zhuǎn)變成為measureSpec
? ? ? ? ? ? ? ? int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, paddingLeft + paddingRight,
? ? ? ? ? ? ? ? ? ? ? ? childLP.width);
? ? ? ? ? ? ? ? int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom,
? ? ? ? ? ? ? ? ? ? ? ? childLP.height);
? ? ? ? ? ? ? ? childView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
? ? ? ? ? ? ? ? //獲取子view的度量寬高
? ? ? ? ? ? ? ? int childMesauredWidth = childView.getMeasuredWidth();
? ? ? ? ? ? ? ? int childMeasuredHeight = childView.getMeasuredHeight();
? ? ? ? ? ? ? ? //如果需要換行
? ? ? ? ? ? ? ? if (childMesauredWidth + lineWidthUsed +mHorizontalSpacing > selfWidth) {
//一旦換行,我們就可以判斷當(dāng)前行需要的寬和高了,所以此時(shí)要記錄下來
? ? ? ? ? ? ? ? ? ? allLines.add(lineViews);
? ? ? ? ? ? ? ? ? ? lineHeights.add(lineHeight);
? ? ? ? ? ? ? ? ? ? parentNeededHeight = parentNeededHeight + lineHeight +mVerticalSpacing;
? ? ? ? ? ? ? ? ? ? parentNeededWidth = Math.max(parentNeededWidth, lineWidthUsed +mHorizontalSpacing);
? ? ? ? ? ? ? ? ? ? lineViews =new ArrayList<>();
? ? ? ? ? ? ? ? ? ? lineWidthUsed =0;
? ? ? ? ? ? ? ? ? ? lineHeight =0;
? ? ? ? ? ? ? ? }
// view 是分行l(wèi)ayout的,所以要記錄每一行有哪些view,這樣可以方便layout布局
? ? ? ? ? ? ? ? lineViews.add(childView);
? ? ? ? ? ? ? ? //每行都會(huì)有自己的寬和高
? ? ? ? ? ? ? ? lineWidthUsed = lineWidthUsed + childMesauredWidth +mHorizontalSpacing;
? ? ? ? ? ? ? ? lineHeight = Math.max(lineHeight, childMeasuredHeight);
? ? ? ? ? ? ? ? //處理最后一行數(shù)據(jù)
? ? ? ? ? ? ? ? if (i == childCount -1) {
allLines.add(lineViews);
? ? ? ? ? ? ? ? ? ? lineHeights.add(lineHeight);
? ? ? ? ? ? ? ? ? ? parentNeededHeight = parentNeededHeight + lineHeight +mVerticalSpacing;
? ? ? ? ? ? ? ? ? ? parentNeededWidth = Math.max(parentNeededWidth, lineWidthUsed +mHorizontalSpacing);
? ? ? ? ? ? ? ? }
}
}
//再度量自己,保存
? ? ? ? //根據(jù)子View的度量結(jié)果,來重新度量自己ViewGroup
? ? ? ? // 作為一個(gè)ViewGroup,它自己也是一個(gè)View,它的大小也需要根據(jù)它的父親給它提供的寬高來度量
? ? ? ? int widthMode = MeasureSpec.getMode(widthMeasureSpec);
? ? ? ? int heightMode = MeasureSpec.getMode(heightMeasureSpec);
? ? ? ? int realWidth = (widthMode == MeasureSpec.EXACTLY) ? selfWidth: parentNeededWidth;
? ? ? ? int realHeight = (heightMode == MeasureSpec.EXACTLY) ?selfHeight: parentNeededHeight;
? ? ? ? setMeasuredDimension(realWidth, realHeight);
? ? }
//布局
? ? @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int lineCount =allLines.size();
? ? ? ? int curL = getPaddingLeft();
? ? ? ? int curT = getPaddingTop();
? ? ? ? for (int i =0; i < lineCount; i++){
List lineViews =allLines.get(i);
? ? ? ? ? ? int lineHeight =lineHeights.get(i);
? ? ? ? ? ? for (int j =0; j < lineViews.size(); j++){
View view = lineViews.get(j);
? ? ? ? ? ? ? ? int left = curL;
? ? ? ? ? ? ? ? int top =? curT;
//? ? ? ? ? ? ? ? int right = left + view.getWidth();
//? ? ? ? ? ? ? ? int bottom = top + view.getHeight();
? ? ? ? ? ? ? ? int right = left + view.getMeasuredWidth();
? ? ? ? ? ? ? ? int bottom = top + view.getMeasuredHeight();
? ? ? ? ? ? ? ? view.layout(left,top,right,bottom);
? ? ? ? ? ? ? ? curL = right +mHorizontalSpacing;
? ? ? ? ? ? }
curT = curT + lineHeight +mVerticalSpacing;
? ? ? ? ? ? curL = getPaddingLeft();
? ? ? ? }
}
//? ? @Override
//? ? protected void onDraw(Canvas canvas) {
//? ? ? ? super.onDraw(canvas);
//? ? }
? ? public static int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
? ? }
}