행당 최대 디스플레이 수를 사용자 정의하여 하위 뷰 너비별로 분할할 수 있는 FlowView
22716 단어 라벨FlowVie 사용자 정의FlowView하위 View 고정폭
// View
private List<List<View>> mAllChildViews = new ArrayList<List<View>>();
//
private List<Integer> mLineHeight = new ArrayList<Integer>();
// 4,
private int lineMaxColumn = 4;
public FlowView(Context context) {
this(context, null);
}
public FlowView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FlowView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
최대 열 수를 설정합니다. 최대 열 수의 값 범위는 1보다 큽니다.
public void setLineMaxColumn(int count) {
if (count < 1) {
this.lineMaxColumn = 1;
} else {
this.lineMaxColumn = count;
}
}
먼저 부모 용기에 전송된 측정 모드와 너비의 계산 값을 얻어서 모든childView를 훑어보고measurechild 방법으로 모든childView를 측정한다.그리고 모든childView의 측정에 따라 이 ViewGroup이 Wrap 으로 설정되면콘텐츠의 넓이와 높음.마지막으로 모드에 따라 MeasureSpec일 경우EXACTLY는 부모 ViewGroup에서 들어오는 너비와 높이를 직접 사용합니다. 그렇지 않으면 스스로 계산한 너비와 높이로 설정됩니다.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
// ViewGroup wrap_content
int width = getPaddingLeft() + getPaddingRight();//
int height = getPaddingTop() + getPaddingBottom();//
//
int lineWidth = 0;
int lineHeight = 0;
// View
int lineViewCount = 0;
// View
int lineViewMaxWidth = 0;
// view
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
boolean lastChild = i == childCount - 1;
// View
if (child.getVisibility() == View.GONE) {
if (lastChild) {
width = Math.max(width, lineWidth);
height += lineHeight;
}
continue;
}
// View
measureChild(child, widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
int childWidthMode = MeasureSpec.AT_MOST;
// View
int childWidthSize = child.getMeasuredWidth();
int childHeightMode = MeasureSpec.AT_MOST;
// View
int childHeightSize = child.getMeasuredHeight();
if (lp.height >= 0) {
childHeightMode = MeasureSpec.EXACTLY;
// childHeightSize = lp.height;
} else if (modeHeight == MeasureSpec.UNSPECIFIED) {
childHeightMode = MeasureSpec.UNSPECIFIED;
childHeightSize = 0;
}
// View
child.measure(MeasureSpec.makeMeasureSpec(childWidthSize,
childWidthMode), MeasureSpec.makeMeasureSpec(
childHeightSize, childHeightMode));
int childWidth = child.getMeasuredWidth() + lp.leftMargin
+ lp.rightMargin;
lineViewMaxWidth = lineViewMaxWidth == 0 ? childWidth : Math.max(
lineViewMaxWidth, childWidth);
//
if (lineWidth + childWidth > sizeWidth
|| (lineMaxColumn > 0 && lineViewCount >= lineMaxColumn)
|| (!checkAddCurLineViews(sizeWidth, lineViewMaxWidth,
lineViewCount))) {
//
width = Math.max(width, lineWidth);
// lineWidth
lineWidth = childWidth;
//
height += lineHeight;
lineHeight = child.getMeasuredHeight() + lp.topMargin
+ lp.bottomMargin;
lineViewCount = 1;
lineViewMaxWidth = childWidth;
} else {//
//
lineWidth += childWidth;
//
lineHeight = Math.max(lineHeight, child.getMeasuredHeight()
+ lp.topMargin + lp.bottomMargin);
lineViewCount++;
}
// View
if (lastChild) {
width = Math.max(width, lineWidth);
height += lineHeight;
}
}
// wrap_content
width += getPaddingLeft() + getPaddingRight();
setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY) ? sizeWidth
: width, (modeHeight == MeasureSpec.EXACTLY) ? sizeHeight
: height);
//
}
현재 행의 모든 뷰 너비를 재계산하여 모든 뷰에 대해 현재 FlowView 너비를 균등하게 나눕니다.
private void reMeasureLineViews(List<View> lineViews) {
// View
int count = lineViews.size();
if (count == 0) {
return;
}
// View
int itemWidth = (this.getMeasuredWidth() - this.getLeftPaddingOffset() - this
.getRightPaddingOffset()) / count;
for (int i = 0; i < count; i++) {
View child = lineViews.get(i);
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
int childWidthSize = itemWidth - lp.leftMargin - lp.rightMargin;
int childHeightSize = child.getMeasuredHeight();
child.measure(MeasureSpec.makeMeasureSpec(childWidthSize,
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
childHeightSize, MeasureSpec.EXACTLY));
}
}
마지막 행 재측정
onLayout에서 모든 childView의 위치 및 크기 지정 완료
private void reMeasureLineViews(List<View> lineViews, int prveLineViewCount) {
// View
int count = lineViews.size();
if (count == 0) {
return;
}
// ,
prveLineViewCount = prveLineViewCount == 0 ? lineMaxColumn
: prveLineViewCount;
// View View , View
if (prveLineViewCount <= count) {
reMeasureLineViews(lineViews);
return;
}
// View View View , View
else if (prveLineViewCount % 2 == 1
&& count > (int) (prveLineViewCount * 1.0 / 2)) {
reMeasureLineViews(lineViews);
return;
}
// View
int prveItemWidth = (this.getMeasuredWidth()
- this.getLeftPaddingOffset() - this.getRightPaddingOffset())
/ prveLineViewCount;
//
int lineViewMaxWidth = 0;
for (int i = 0; i < count; i++) {
View child = lineViews.get(i);
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
lineViewMaxWidth = Math.max(lineViewMaxWidth,
child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
}
// View , View 2 , 。
int itemWidth = prveItemWidth;
if (prveItemWidth < lineViewMaxWidth) {
if (prveLineViewCount % 2 == 0
|| count > (int) (prveLineViewCount * 1.0 / 2)) {
reMeasureLineViews(lineViews);
return;
}
itemWidth = 2 * prveItemWidth;
}
for (int i = 0; i < count; i++) {
View child = lineViews.get(i);
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
int childWidthSize = itemWidth - lp.leftMargin - lp.rightMargin;
int childHeightSize = child.getMeasuredHeight();
child.measure(MeasureSpec.makeMeasureSpec(childWidthSize,
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
childHeightSize, MeasureSpec.EXACTLY));
}
}
현재 행에 추가할 수 있는지 확인
private boolean checkAddCurLineViews(int totalWidth, int maxWidth,
int curCount) {
if (totalWidth / (curCount + 1) > maxWidth) {
return true;
}
return false;
}
@SuppressLint("DrawAllocation")
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mAllChildViews.clear();
mLineHeight.clear();
// ViewGroup
int width = getWidth();
int lineWidth = 0;
int lineHeight = 0;
//
int lineItemMaxWidth = 0;
//
int prevLineViewCount = 0;
// view
List<View> lineViews = new ArrayList<View>();
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
boolean lastChild = i == childCount - 1;
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
//
if ((lineViews.size() != 0 && childWidth + lineWidth
+ lp.leftMargin + lp.rightMargin > width)
|| (lineMaxColumn > 0 && lineViews.size() >= lineMaxColumn)) {
mAllChildViews.add(lineViews);
// LineHeight
mLineHeight.add(lineHeight);
// Views
reMeasureLineViews(lineViews);
prevLineViewCount = lineViews.size();
//
lineWidth = 0;
lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
// view
lineViews = new ArrayList<View>();
lineItemMaxWidth = 0;
}
lineItemMaxWidth = lineItemMaxWidth == 0 ? childWidth
+ lp.leftMargin + lp.rightMargin : Math.max(
lineItemMaxWidth, childWidth + lp.leftMargin
+ lp.rightMargin);
if (!checkAddCurLineViews(width, lineItemMaxWidth, lineViews.size())) {
if (lineViews.size() != 0) {
mAllChildViews.add(lineViews);
}
// LineHeight
mLineHeight.add(lineHeight);
// Views
reMeasureLineViews(lineViews);
prevLineViewCount = lineViews.size();
//
lineWidth = 0;
lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
// view
lineViews = new ArrayList<View>();
lineItemMaxWidth = childWidth + lp.leftMargin + lp.rightMargin;
}
lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
lineHeight = Math.max(lineHeight, childHeight + lp.topMargin
+ lp.bottomMargin);
lineViews.add(child);
if (lastChild) {
//
mLineHeight.add(lineHeight);
mAllChildViews.add(lineViews);
// Views
reMeasureLineViews(lineViews, prevLineViewCount);
}
}
// View
int left = 0;
int top = 0;
//
int lineCount = mAllChildViews.size();
for (int i = 0; i < lineCount; i++) {
// views
lineViews = mAllChildViews.get(i);
lineHeight = mLineHeight.get(i);
for (int j = 0; j < lineViews.size(); j++) {
View child = lineViews.get(j);
//
if (child.getVisibility() == View.GONE) {
continue;
}
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
int cLeft = left + lp.leftMargin;
int cTop = top + lp.topMargin;
int cRight = cLeft + child.getMeasuredWidth();
int cBottom = cTop + child.getMeasuredHeight();
// View
child.layout(cLeft, cTop, cRight, cBottom);
left += child.getMeasuredWidth() + lp.leftMargin
+ lp.rightMargin;
}
left = 0;
top += lineHeight;
}
}
현재 ViewGroup에 해당하는 LayoutParams
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
전체 코드 다운로드 주소
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
비프로그램 디자인으로 iMessage용 라벨을 만들면아이폰/아이패드 쓰시는 분들 아이메시지 스티커 있으신가요?솔직히 말하면 실제 상황은 그다지 사용되지 않는다.나는 라벨을 거의 받지 못했기 때문이다. 이 기사에서 나는 그런 이야기를 할 것이다. 위에서 말한 바와 같이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.