這篇文章給大家分享的是有關(guān)Android如何自定義ViewGroup實(shí)現(xiàn)堆疊頭像的點(diǎn)贊Layout的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
專業(yè)領(lǐng)域包括成都做網(wǎng)站、網(wǎng)站建設(shè)、外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè)、成都商城網(wǎng)站開(kāi)發(fā)、微信營(yíng)銷(xiāo)、系統(tǒng)平臺(tái)開(kāi)發(fā), 與其他網(wǎng)站設(shè)計(jì)及系統(tǒng)開(kāi)發(fā)公司不同,創(chuàng)新互聯(lián)的整合解決方案結(jié)合了幫做網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗(yàn)和互聯(lián)網(wǎng)整合營(yíng)銷(xiāo)的理念,并將策略和執(zhí)行緊密結(jié)合,為客戶提供全網(wǎng)互聯(lián)網(wǎng)整合方案。
實(shí)現(xiàn)
自定義屬性
屬性名 | 說(shuō)明 | 默認(rèn)值 |
---|---|---|
vertivalSpace | 行距 | 4dp |
pileWidth | 重疊寬度 | 10dp |
onMeasure方法,每行的寬度不再是child的寬度和了,而是要減掉重疊部分的寬度和
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); //AT_MOST int width = 0; int height = 0; int rawWidth = 0;//當(dāng)前行總寬度 int rawHeight = 0;// 當(dāng)前行高 int rowIndex = 0;//當(dāng)前行位置 int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); if(child.getVisibility() == GONE){ if(i == count - 1){ //最后一個(gè)child height += rawHeight; width = Math.max(width, rawWidth); } continue; } //這里調(diào)用measureChildWithMargins 而不是measureChild measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; if(rawWidth + childWidth - (rowIndex > 0 ? pileWidth : 0)> widthSpecSize - getPaddingLeft() - getPaddingRight()){ //換行 width = Math.max(width, rawWidth); rawWidth = childWidth; height += rawHeight + vertivalSpace; rawHeight = childHeight; rowIndex = 0; } else { rawWidth += childWidth; if(rowIndex > 0){ rawWidth -= pileWidth; } rawHeight = Math.max(rawHeight, childHeight); } if(i == count - 1){ width = Math.max(rawWidth, width); height += rawHeight; } rowIndex++; } setMeasuredDimension( widthSpecMode == MeasureSpec.EXACTLY ? widthSpecSize : width + getPaddingLeft() + getPaddingRight(), heightSpecMode == MeasureSpec.EXACTLY ? heightSpecSize : height + getPaddingTop() + getPaddingBottom() ); }
onLayout 每一行,第一個(gè)正常放,之后的重疊放
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int viewWidth = r - l; int leftOffset = getPaddingLeft(); int topOffset = getPaddingTop(); int rowMaxHeight = 0; int rowIndex = 0;//當(dāng)前行位置 View childView; for( int w = 0, count = getChildCount(); w < count; w++ ){ childView = getChildAt(w); if(childView.getVisibility() == GONE) continue; MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams(); // 如果加上當(dāng)前子View的寬度后超過(guò)了ViewGroup的寬度,就換行 int occupyWidth = lp.leftMargin + childView.getMeasuredWidth() + lp.rightMargin; if(leftOffset + occupyWidth + getPaddingRight() > viewWidth){ leftOffset = getPaddingLeft(); // 回到最左邊 topOffset += rowMaxHeight + vertivalSpace; // 換行 rowMaxHeight = 0; rowIndex = 0; } int left = leftOffset + lp.leftMargin; int top = topOffset + lp.topMargin; int right = leftOffset+ lp.leftMargin + childView.getMeasuredWidth(); int bottom = topOffset + lp.topMargin + childView.getMeasuredHeight(); childView.layout(left, top, right, bottom); // 橫向偏移 leftOffset += occupyWidth; // 試圖更新本行最高View的高度 int occupyHeight = lp.topMargin + childView.getMeasuredHeight() + lp.bottomMargin; if(rowIndex != count - 1){ leftOffset -= pileWidth;//這里控制重疊位置 } rowMaxHeight = Math.max(rowMaxHeight, occupyHeight); rowIndex++; } }
效果圖
因?yàn)檫@個(gè)一般只會(huì)顯示一行,所以暫時(shí)沒(méi)有通過(guò)setAdapter方式去設(shè)置數(shù)據(jù)源。
感謝各位的閱讀!關(guān)于“Android如何自定義ViewGroup實(shí)現(xiàn)堆疊頭像的點(diǎn)贊Layout”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!