android高級(jí)ui01-自定義view-

學(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());

? ? }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容