下面列出了android.view.ViewGroup#getChildMeasureSpec ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
protected @NonNull RecyclerView.ViewHolder getHeader(RecyclerView parent, StickyHeaderAdapter stickyAdapter, int position) {
StickyHeaderViewHolder viewHolder = new StickyHeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.conversation_item_last_seen, parent, false));
adapter.onBindLastSeenViewHolder(viewHolder, position);
int widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY);
int heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.UNSPECIFIED);
int childWidth = ViewGroup.getChildMeasureSpec(widthSpec, parent.getPaddingLeft() + parent.getPaddingRight(), viewHolder.itemView.getLayoutParams().width);
int childHeight = ViewGroup.getChildMeasureSpec(heightSpec, parent.getPaddingTop() + parent.getPaddingBottom(), viewHolder.itemView.getLayoutParams().height);
viewHolder.itemView.measure(childWidth, childHeight);
viewHolder.itemView.layout(0, 0, viewHolder.itemView.getMeasuredWidth(), viewHolder.itemView.getMeasuredHeight());
return viewHolder;
}
private void measureView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
/**
* measure header layout
*
* @param child
*/
private void measureHeaderLayout(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
/**
* 测量视图尺寸
*
* @param view 视图
* @return arr[0]: 视图宽度, arr[1]: 视图高度
*/
public static int[] measureView(View view) {
ViewGroup.LayoutParams lp = view.getLayoutParams();
if (lp == null) {
lp = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
}
int widthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
int lpHeight = lp.height;
int heightSpec;
if (lpHeight > 0) {
heightSpec = View.MeasureSpec.makeMeasureSpec(lpHeight, View.MeasureSpec.EXACTLY);
} else {
heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
}
view.measure(widthSpec, heightSpec);
return new int[]{view.getMeasuredWidth(), view.getMeasuredHeight()};
}
private void measureScrapChild(View child, int position, int widthMeasureSpec) {
LayoutParams p = (LayoutParams) child.getLayoutParams();
if (p == null) {
p = (ZrcAbsListView.LayoutParams) generateDefaultLayoutParams();
child.setLayoutParams(p);
}
p.viewType = mAdapter.getItemViewType(position);
p.forceAdd = true;
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
mListPadding.left + mListPadding.right,
p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
private void measureItem(View item) {
ViewGroup.LayoutParams lp = item.getLayoutParams();
if (lp == null) {
lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
item.setLayoutParams(lp);
}
int wspec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getListPaddingLeft()
+ getListPaddingRight(), lp.width);
int hspec;
if (lp.height > 0) {
hspec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
} else {
hspec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
item.measure(wspec, hspec);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
try {
View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
/**
* Measure a particular list child. TODO: unify with setUpChild.
*
* @param child
* The child.
*/
private void measureItem( View child ) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if ( p == null ) {
p = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.MATCH_PARENT );
}
int childHeightSpec = ViewGroup.getChildMeasureSpec( mHeightMeasureSpec, mListPadding.top + mListPadding.bottom, p.height );
int lpWidth = p.width;
int childWidthSpec;
if ( lpWidth > 0 ) {
childWidthSpec = MeasureSpec.makeMeasureSpec( lpWidth, MeasureSpec.EXACTLY );
} else {
childWidthSpec = MeasureSpec.makeMeasureSpec( 0, MeasureSpec.UNSPECIFIED );
}
child.measure( childWidthSpec, childHeightSpec );
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
if (position < getItemCount()) {
try {
View view = recycler.getViewForPosition(position);//fix 动态添加时报IndexOutOfBoundsException
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void measureItem(@NonNull View item) {
ViewGroup.LayoutParams lp = item.getLayoutParams();
if (lp == null) {
lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
item.setLayoutParams(lp);
}
int wspec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getListPaddingLeft()
+ getListPaddingRight(), lp.width);
int hspec;
if (lp.height > 0) {
hspec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
} else {
hspec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
item.measure(wspec, hspec);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
View view = recycler.getViewForPosition(position);
// For adding Item Decor Insets to view
super.measureChildWithMargins(view, 0, 0);
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view),
p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom() + getPaddingBottom() + getDecoratedBottom(view),
p.height);
view.measure(childWidthSpec, childHeightSpec);
// Get decorated measurements
measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin;
measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
/**
* Measure the view.
*
* @param view The view.
* @return arr[0]: view's width, arr[1]: view's height
*/
public static int[] measureView(final View view) {
ViewGroup.LayoutParams lp = view.getLayoutParams();
if (lp == null) {
lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int widthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
int lpHeight = lp.height;
int heightSpec;
if (lpHeight > 0) {
heightSpec = View.MeasureSpec.makeMeasureSpec(lpHeight, View.MeasureSpec.EXACTLY);
} else {
heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
}
view.measure(widthSpec, heightSpec);
return new int[]{view.getMeasuredWidth(), view.getMeasuredHeight()};
}
private void measureScrapChild(View child, int position, int widthMeasureSpec) {
ListView.LayoutParams p = (ListView.LayoutParams) child.getLayoutParams();
if (p == null) {
p = new ListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0);
child.setLayoutParams(p);
}
//XXX p.viewType = mAdapter.getItemViewType(position);
//XXX p.forceAdd = true;
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
mDropDownList.getPaddingLeft() + mDropDownList.getPaddingRight(), p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
if (getChildCount() == 0) {
return;
}
View view = recycler.getViewForPosition(position);
if (view.getVisibility() == View.GONE) {
measuredDimension[0] = 0;
measuredDimension[1] = 0;
return;
}
// For adding Item Decor Insets to view
super.measureChildWithMargins(view, 0, 0);
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(
widthSpec,
getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(
view),
p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(
heightSpec,
getPaddingTop() + getPaddingBottom() + getDecoratedTop(view) + getDecoratedBottom(view),
p.height);
view.measure(childWidthSpec, childHeightSpec);
// Get decorated measurements
measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin;
measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
@Override
public View getHeader(RecyclerView parent, int position) {
long headerId = mAdapter.getHeaderId(position);
View header = mHeaderViews.get(headerId);
if (header == null) {
//TODO - recycle views
RecyclerView.ViewHolder viewHolder = mAdapter.onCreateHeaderViewHolder(parent);
mAdapter.onBindHeaderViewHolder(viewHolder, position);
header = viewHolder.itemView;
if (header.getLayoutParams() == null) {
header.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
int widthSpec;
int heightSpec;
if (mOrientationProvider.getOrientation(parent) == LinearLayoutManager.VERTICAL) {
widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY);
heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.UNSPECIFIED);
} else {
widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.UNSPECIFIED);
heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.EXACTLY);
}
int childWidth = ViewGroup.getChildMeasureSpec(widthSpec,
parent.getPaddingLeft() + parent.getPaddingRight(), header.getLayoutParams().width);
int childHeight = ViewGroup.getChildMeasureSpec(heightSpec,
parent.getPaddingTop() + parent.getPaddingBottom(), header.getLayoutParams().height);
header.measure(childWidth, childHeight);
header.layout(0, 0, header.getMeasuredWidth(), header.getMeasuredHeight());
mHeaderViews.put(headerId, header);
}
return header;
}
/**
* Add a view as a child and make sure it is measured (if necessary) and
* positioned properly.
*
* @param child The view to add
* @param position The position of this child
* @param y The y position relative to which this view will be positioned
* @param flowDown If true, align top edge to y. If false, align bottom
* edge to y.
* @param childrenLeft Left edge where children should be positioned
* @param selected Is this position selected?
* @param recycled Has this view been pulled from the recycle bin? If so it
* does not need to be remeasured.
*/
private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,
boolean selected, boolean recycled) {
final boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
final int mode = mTouchMode;
final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL &&
mMotionPosition == position;
final boolean updateChildPressed = isPressed != child.isPressed();
final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make some up...
// noinspection unchecked
LayoutParams p = (LayoutParams) child.getLayoutParams();
if (p == null) {
p = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0);
}
p.viewType = mAdapter.getItemViewType(position);
p.scrappedFromPosition = position;
if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter &&
p.viewType == PLAAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
attachViewToParent(child, flowDown ? -1 : 0, p);
} else {
p.forceAdd = false;
if (p.viewType == PLAAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
p.recycledHeaderFooter = true;
}
addViewInLayout(child, flowDown ? -1 : 0, p, true);
}
if (updateChildSelected) {
child.setSelected(isSelected);
}
if (updateChildPressed) {
child.setPressed(isPressed);
}
if (needToMeasure) {
int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = View.MeasureSpec.makeMeasureSpec(lpHeight, View.MeasureSpec.EXACTLY);
} else {
childHeightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
}
onMeasureChild( child, position, childWidthSpec, childHeightSpec );
//child.measure(childWidthSpec, childHeightSpec);
} else {
cleanupLayoutState(child);
}
final int w = child.getMeasuredWidth();
final int h = child.getMeasuredHeight();
final int childTop = flowDown ? y : y - h;
if (needToMeasure) {
final int childRight = childrenLeft + w;
final int childBottom = childTop + h;
//child.layout(childrenLeft, childTop, childRight, childBottom);
onLayoutChild(child, position, childrenLeft, childTop, childRight, childBottom);
} else {
final int offsetLeft = childrenLeft - child.getLeft();
final int offsetTop = childTop - child.getTop();
onOffsetChild(child, position, offsetLeft, offsetTop);
}
if (mCachingStarted && !child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
}
private void createFloatingGroupView(int position) {
mFloatingGroupView = null;
mFloatingGroupPosition = getPackedPositionGroup(getExpandableListPosition(position));
for(int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
final Object tag = child.getTag(R.id.fgelv_tag_changed_visibility);
if(tag instanceof Boolean) {
final boolean changedVisibility = (Boolean) tag;
if(changedVisibility) {
child.setVisibility(View.VISIBLE);
child.setTag(R.id.fgelv_tag_changed_visibility, null);
}
}
}
if(!mFloatingGroupEnabled) {
return;
}
final int floatingGroupFlatPosition = getFlatListPosition(getPackedPositionForGroup(mFloatingGroupPosition));
final int floatingGroupListPosition = floatingGroupFlatPosition - position;
if(floatingGroupListPosition >= 0 && floatingGroupListPosition < getChildCount()) {
final View currentGroupView = getChildAt(floatingGroupListPosition);
if(currentGroupView.getTop() >= getPaddingTop()) {
return;
} else if(currentGroupView.getTop() < getPaddingTop() && currentGroupView.getVisibility() == View.VISIBLE) {
currentGroupView.setVisibility(View.INVISIBLE);
currentGroupView.setTag(R.id.fgelv_tag_changed_visibility, true);
}
}
if(mFloatingGroupPosition >= 0) {
mFloatingGroupView = mAdapter.getGroupView(mFloatingGroupPosition, mAdapter.isGroupExpanded(mFloatingGroupPosition), mFloatingGroupView, this);
if(!mFloatingGroupView.isClickable()) {
mSelectorEnabled = true;
mFloatingGroupView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
postDelayed(mOnClickAction, ViewConfiguration.getPressedStateDuration());
}
});
} else {
mSelectorEnabled = false;
}
loadAttachInfo();
setAttachInfo(mFloatingGroupView);
}
if(mFloatingGroupView == null) {
return;
}
AbsListView.LayoutParams params = (AbsListView.LayoutParams) mFloatingGroupView.getLayoutParams();
if(params == null) {
params = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0);
mFloatingGroupView.setLayoutParams(params);
}
final int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getPaddingLeft() + getPaddingRight(), params.width);
final int paramsHeight = params.height;
int childHeightSpec;
if(paramsHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(paramsHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0 , MeasureSpec.UNSPECIFIED);
}
mFloatingGroupView.measure(childWidthSpec, childHeightSpec);
int floatingGroupScrollY = 0;
final int nextGroupFlatPosition = getFlatListPosition(getPackedPositionForGroup(mFloatingGroupPosition + 1));
final int nextGroupListPosition = nextGroupFlatPosition - position;
if(nextGroupListPosition >= 0 && nextGroupListPosition < getChildCount()) {
final View nextGroupView = getChildAt(nextGroupListPosition);
if(nextGroupView != null && nextGroupView.getTop() < getPaddingTop() + mFloatingGroupView.getMeasuredHeight() + getDividerHeight()) {
floatingGroupScrollY = nextGroupView.getTop() - (getPaddingTop() + mFloatingGroupView.getMeasuredHeight() + getDividerHeight());
}
}
final int left = getPaddingLeft();
final int top = getPaddingTop() + floatingGroupScrollY;
final int right = left + mFloatingGroupView.getMeasuredWidth();
final int bottom = top + mFloatingGroupView.getMeasuredHeight();
mFloatingGroupView.layout(left, top, right, bottom);
mFloatingGroupScrollY = floatingGroupScrollY;
if(mOnScrollFloatingGroupListener != null) {
mOnScrollFloatingGroupListener.onScrollFloatingGroupListener(mFloatingGroupView, mFloatingGroupScrollY);
}
}
/**
* Add a view as a child and make sure it is measured (if necessary) and
* positioned properly.
*
* @param child The view to add
* @param position The position of this child
* @param y The y position relative to which this view will be positioned
* @param flowDown If true, align top edge to y. If false, align bottom edge
* to y.
* @param childrenLeft Left edge where children should be positioned
* @param selected Is this position selected?
* @param recycled Has this view been pulled from the recycle bin? If so it
* does not need to be remeasured.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,
boolean selected,
boolean recycled) {
final boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
final int mode = mTouchMode;
final boolean isPressed =
mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL && mMotionPosition == position;
final boolean updateChildPressed = isPressed != child.isPressed();
final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make
// some up...
// noinspection unchecked
ZrcAbsListView.LayoutParams p = (ZrcAbsListView.LayoutParams) child.getLayoutParams();
if (p == null) {
p = (ZrcAbsListView.LayoutParams) generateDefaultLayoutParams();
}
p.viewType = mAdapter.getItemViewType(position);
if ((recycled && !p.forceAdd)
|| (p.recycledHeaderFooter &&
p.viewType == ZrcAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
attachViewToParent(child, flowDown ? -1 : 0, p);
} else {
p.forceAdd = false;
if (p.viewType == ZrcAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
p.recycledHeaderFooter = true;
}
addViewInLayout(child, flowDown ? -1 : 0, p, true);
}
if (updateChildSelected) {
child.setSelected(isSelected);
}
if (updateChildPressed) {
child.setPressed(isPressed);
}
if (needToMeasure) {
int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, mListPadding.left
+ mListPadding.right, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
} else {
cleanupLayoutState(child);
}
final int w = child.getMeasuredWidth();
final int h = child.getMeasuredHeight();
final int childTop = flowDown ? y : y - h;
if (needToMeasure) {
final int childRight = childrenLeft + w;
final int childBottom = childTop + h;
child.layout(childrenLeft, childTop, childRight, childBottom);
} else {
child.offsetLeftAndRight(childrenLeft - child.getLeft());
child.offsetTopAndBottom(childTop - child.getTop());
}
if (mCachingStarted && !child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
if (recycled &&
(((ZrcAbsListView.LayoutParams) child.getLayoutParams()).scrappedFromPosition) !=
position) {
if (APIUtil.isSupport(11)) {
child.jumpDrawablesToCurrentState();
}
}
}
@Override
public void measureFooter(
@NonNull IRefreshView<IIndicator> footer, int widthMeasureSpec, int heightMeasureSpec) {
if (mLayout.isDisabledLoadMore()) {
return;
}
final View child = footer.getView();
final IIndicator indicator = mLayout.getIndicator();
final SmoothRefreshLayout.LayoutParams lp =
(SmoothRefreshLayout.LayoutParams) footer.getView().getLayoutParams();
int size = footer.getCustomHeight();
if (footer.getStyle() == IRefreshView.STYLE_DEFAULT
|| footer.getStyle() == IRefreshView.STYLE_PIN
|| footer.getStyle() == IRefreshView.STYLE_FOLLOW_CENTER
|| footer.getStyle() == IRefreshView.STYLE_FOLLOW_PIN) {
if (size <= 0) {
if (size == SmoothRefreshLayout.LayoutParams.MATCH_PARENT) {
lp.width = SmoothRefreshLayout.LayoutParams.MATCH_PARENT;
}
} else {
lp.width = size;
}
measureChildWithMargins(child, widthMeasureSpec, heightMeasureSpec);
setFooterHeight(child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
} else {
if (size <= 0 && size != SmoothRefreshLayout.LayoutParams.MATCH_PARENT) {
throw new IllegalArgumentException(
"If footer view type is "
+ "STYLE_SCALE or STYLE_FOLLOW_SCALE, you must set a accurate height");
} else {
if (size == SmoothRefreshLayout.LayoutParams.MATCH_PARENT) {
int specSize = View.MeasureSpec.getSize(heightMeasureSpec);
size =
Math.max(
0,
specSize
- (mLayout.getPaddingLeft()
+ mLayout.getPaddingRight()
+ lp.leftMargin
+ lp.rightMargin));
setFooterHeight(size);
} else {
setFooterHeight(size + lp.leftMargin + lp.rightMargin);
}
}
if (footer.getStyle() == IRefreshView.STYLE_FOLLOW_SCALE) {
if (indicator.getCurrentPos() <= indicator.getFooterHeight()) {
lp.width = size;
measureChildWithMargins(child, widthMeasureSpec, heightMeasureSpec);
return;
}
}
final int childHeightMeasureSpec =
ViewGroup.getChildMeasureSpec(
heightMeasureSpec,
mLayout.getPaddingTop()
+ mLayout.getPaddingBottom()
+ lp.topMargin
+ lp.bottomMargin,
lp.height);
final int childWidthMeasureSpec;
if (mLayout.isMovingFooter()) {
final int maxWidth =
View.MeasureSpec.getSize(widthMeasureSpec)
- mLayout.getPaddingLeft()
- mLayout.getPaddingRight()
- lp.leftMargin
- lp.rightMargin;
int realWidth =
Math.min(
indicator.getCurrentPos() - lp.leftMargin - lp.rightMargin,
maxWidth);
childWidthMeasureSpec =
View.MeasureSpec.makeMeasureSpec(
Math.max(realWidth, 0), View.MeasureSpec.EXACTLY);
} else {
childWidthMeasureSpec =
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.EXACTLY);
}
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
/**
* Add a view as a child and make sure it is measured (if necessary) and
* positioned properly.
*
* @param child The view to add
* @param position The position of the view
* @param y The y position relative to which this view will be positioned
* @param flow if true, align top edge to y. If false, align bottom edge
* to y.
* @param childrenLeft Left edge where children should be positioned
* @param selected Is this position selected?
* @param recycled Has this view been pulled from the recycle bin? If so it
* does not need to be remeasured.
* @param where Where to add the item in the list
*
*/
private void setupChild(View child, int position, int y, boolean flow, int childrenLeft,
boolean selected, boolean recycled, int where) {
boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
final int mode = mTouchMode;
final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL &&
mMotionPosition == position;
final boolean updateChildPressed = isPressed != child.isPressed();
boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make
// some up...
TwoWayAbsListView.LayoutParams p = (TwoWayAbsListView.LayoutParams)child.getLayoutParams();
if (p == null) {
p = new TwoWayAbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0);
}
p.viewType = mAdapter.getItemViewType(position);
if (recycled && !p.forceAdd) {
attachViewToParent(child, where, p);
} else {
p.forceAdd = false;
addViewInLayout(child, where, p, true);
}
if (updateChildSelected) {
child.setSelected(isSelected);
if (isSelected) {
requestFocus();
}
}
if (updateChildPressed) {
child.setPressed(isPressed);
}
if (needToMeasure) {
int childHeightSpec = ViewGroup.getChildMeasureSpec(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height);
int childWidthSpec = ViewGroup.getChildMeasureSpec(
MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width);
child.measure(childWidthSpec, childHeightSpec);
} else {
cleanupLayoutState(child);
}
final int w = child.getMeasuredWidth();
final int h = child.getMeasuredHeight();
int childLeft;
final int childTop = flow ? y : y - h;
switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
case Gravity.LEFT:
childLeft = childrenLeft;
break;
case Gravity.CENTER_HORIZONTAL:
childLeft = childrenLeft + ((mColumnWidth - w) / 2);
break;
case Gravity.RIGHT:
childLeft = childrenLeft + mColumnWidth - w;
break;
default:
childLeft = childrenLeft;
break;
}
if (needToMeasure) {
final int childRight = childLeft + w;
final int childBottom = childTop + h;
child.layout(childLeft, childTop, childRight, childBottom);
} else {
child.offsetLeftAndRight(childLeft - child.getLeft());
child.offsetTopAndBottom(childTop - child.getTop());
}
if (mCachingStarted) {
child.setDrawingCacheEnabled(true);
}
}