Created
September 9, 2016 07:42
-
-
Save solohsu/5ef585718bf04546d01ec065532ba16c to your computer and use it in GitHub Desktop.
WidthAutoAdjustLinearLayout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.widget.LinearLayout; | |
/** | |
* 根据可以完整显示的所有子view的总宽度自动调整自身的宽度. | |
* <p/> | |
* 当第n个childView可以完整显示,第n+1个childView无法完整显示时,不显示n+1及其以后的childView, | |
* 并将宽度调整为n个childView的总宽度. | |
* <p/> | |
* Created by soloslxu on 2015/12/21. | |
*/ | |
public class WidthAutoAdjustLinearLayout extends LinearLayout { | |
public WidthAutoAdjustLinearLayout(Context context) { | |
this(context, null); | |
} | |
public WidthAutoAdjustLinearLayout(Context context, AttributeSet attrs) { | |
this(context, attrs, 0); | |
} | |
public WidthAutoAdjustLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { | |
super(context, attrs, defStyleAttr); | |
setOrientation(HORIZONTAL); | |
} | |
@Override | |
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
// 减左右padding后得到children可用的宽度 | |
int availableWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight(); | |
int totalWidth = 0; | |
int maxTotalWidth = -1; | |
boolean maxChildIndexFound = false; | |
for (int i = 0; i < getChildCount(); i++) { | |
View child = getChildAt(i); | |
if (child == null || child.getVisibility() == GONE) { | |
continue; | |
} | |
if (maxChildIndexFound) { | |
// 已找到最多可容纳的child,后面的child都设为GONE,直接跳过layout | |
child.setVisibility(GONE); | |
} else { | |
LayoutParams lp = (LayoutParams) child.getLayoutParams(); | |
// 获取childView不被截断时的完整宽度,不要重新measure height, | |
// 否则会使child的height的match_parent属性无效 | |
child.measure(0, heightMeasureSpec); | |
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; | |
totalWidth += childWidth; | |
if (totalWidth > availableWidth) { | |
// 记录可完整显示的children的总长度 | |
maxChildIndexFound = true; | |
if (i == 0) { | |
// 如果第一个长度就超了,对第一个进行截断处理,不要GONE掉 | |
maxTotalWidth = availableWidth; | |
child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY), | |
MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), MeasureSpec.EXACTLY)); | |
} else { | |
// 后面的如果超了,GONE掉 | |
maxTotalWidth = totalWidth - childWidth; | |
child.setVisibility(GONE); | |
} | |
} else if (totalWidth == availableWidth) { | |
// 如果前0~i正好达到最大宽度,第i个child的宽度不需要减掉,也不需要隐藏, | |
// 仅需记录标志位,让后面的child隐藏。 | |
maxChildIndexFound = true; | |
maxTotalWidth = totalWidth; | |
} | |
} | |
} | |
// 重设宽度 | |
if (maxChildIndexFound) { | |
// 不能完整显示所有child,设为计算出的最大宽度maxTotalWidth | |
setMeasuredDimension(maxTotalWidth, getMeasuredHeight()); | |
} else { | |
// 可以完整显示所有child,设为所有child的总宽度之和 | |
setMeasuredDimension(totalWidth, getMeasuredHeight()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment