下面列出了android.view.View#getBaseline ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public int getBaseline() {
View child = null;
if (getChildCount() > 0) {
child = getChildAt(0);
} else if (mAdapter != null && mAdapter.getCount() > 0) {
child = makeAndAddView(0);
mRecycler.put(0, child);
removeAllViewsInLayout();
}
if (child != null) {
final int childBaseline = child.getBaseline();
return childBaseline >= 0 ? child.getTop() + childBaseline : -1;
} else {
return -1;
}
}
@Override
public int getBaseline() {
View child = null;
if (getChildCount() > 0) {
child = getChildAt(0);
} else if (mAdapter != null && mAdapter.getCount() > 0) {
child = makeView(0, false);
mRecycler.put(0, child);
}
if (child != null) {
final int childBaseline = child.getBaseline();
return childBaseline >= 0 ? child.getTop() + childBaseline : -1;
} else {
return -1;
}
}
@Override
public int getBaseline() {
View child = null;
if (getChildCount() > 0) {
child = getChildAt(0);
} else if (mAdapter != null && mAdapter.getCount() > 0) {
child = makeAndAddView(0);
mRecycler.put(0, child);
removeAllViewsInLayout();
}
if (child != null) {
final int childBaseline = child.getBaseline();
return childBaseline >= 0 ? child.getTop() + childBaseline : -1;
} else {
return -1;
}
}
@Override
public int getBaseline() {
View child = null;
if (getChildCount() > 0) {
child = getChildAt(0);
} else if (mAdapter != null && mAdapter.getCount() > 0) {
child = makeAndAddView(0);
mRecycler.put(0, child);
removeAllViewsInLayout();
}
if (child != null) {
final int childBaseline = child.getBaseline();
return childBaseline >= 0 ? child.getTop() + childBaseline : -1;
} else {
return -1;
}
}
@Override
public int getBaseline() {
View child = null;
if (getChildCount() > 0) {
child = getChildAt(0);
} else if (mAdapter != null && mAdapter.getCount() > 0) {
child = makeAndAddView(0);
mRecycler.put(0, child);
removeAllViewsInLayout();
}
if (child != null) {
final int childBaseline = child.getBaseline();
return childBaseline >= 0 ? child.getTop() + childBaseline : -1;
} else {
return -1;
}
}
@Override
public int getAlignmentValue(View view, int viewSize, int mode) {
if (view.getVisibility() == GONE) {
return 0;
}
int baseline = view.getBaseline();
return baseline == -1 ? UNDEFINED : baseline;
}
private int getRelatedViewBaselineOffset(int[] rules) {
final View v = getRelatedView(rules, ALIGN_BASELINE);
if (v != null) {
final int baseline = v.getBaseline();
if (baseline != -1) {
final ViewGroup.LayoutParams params = v.getLayoutParams();
if (params instanceof LayoutParams) {
final LayoutParams anchorParams = (LayoutParams) v.getLayoutParams();
return anchorParams.mTop + baseline;
}
}
}
return -1;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
View mTitleView = getRootView().findViewById(android.support.v17.leanback.R.id.guidance_title);
View mBreadcrumbView = getRootView().findViewById(android.support.v17.leanback.R.id.guidance_breadcrumb);
View mDescriptionView = getRootView().findViewById(
android.support.v17.leanback.R.id.guidance_description);
ImageView mIconView = getRootView().findViewById(android.support.v17.leanback.R.id.guidance_icon);
int mTitleKeylinePixels = (int) (getMeasuredHeight() * mTitleKeylinePercent / 100);
if (mTitleView != null && mTitleView.getParent() == this) {
int titleViewBaseline = mTitleView.getBaseline();
int mBreadcrumbViewHeight = mBreadcrumbView == null ? 0 : mBreadcrumbView.getMeasuredHeight();
int guidanceTextContainerTop = mTitleKeylinePixels
- titleViewBaseline - mBreadcrumbViewHeight - mTitleView.getPaddingTop();
int offset = guidanceTextContainerTop - (mBreadcrumbView == null ? 0 : mBreadcrumbView.getTop());
if (mBreadcrumbView != null && mBreadcrumbView.getParent() == this) {
mBreadcrumbView.offsetTopAndBottom(offset);
}
mTitleView.offsetTopAndBottom(offset);
if (mDescriptionView != null && mDescriptionView.getParent() == this) {
mDescriptionView.offsetTopAndBottom(offset);
}
}
if (mIconView != null && mIconView.getParent() == this) {
Drawable drawable = mIconView.getDrawable();
if (drawable != null && mDescriptionView != null) {
int iconOffset = mDescriptionView.getBottom() - mIconView.getBottom();
mIconView.offsetTopAndBottom(
iconOffset);
}
}
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int count = getChildCount();
int maxWidth = 0;
int maxHeight = 0;
int maxChildBaseline = -1;
int maxChildDescent = -1;
int childState = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
measureChild(child, widthMeasureSpec, heightMeasureSpec);
final int baseline = child.getBaseline();
if (baseline != -1) {
maxChildBaseline = Math.max(maxChildBaseline, baseline);
maxChildDescent = Math.max(maxChildDescent, child.getMeasuredHeight() - baseline);
}
maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
childState = ViewUtils.combineMeasuredStates(childState,
ViewCompat.getMeasuredState(child));
}
if (maxChildBaseline != -1) {
maxHeight = Math.max(maxHeight, maxChildBaseline + maxChildDescent);
mBaseline = maxChildBaseline;
}
maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
setMeasuredDimension(
ViewCompat.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
ViewCompat.resolveSizeAndState(maxHeight, heightMeasureSpec,
childState << MEASURED_HEIGHT_STATE_SHIFT));
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
final int count = getChildCount();
final int parentLeft = getPaddingLeft();
final int parentRight = right - left - getPaddingRight();
final int parentContentWidth = parentRight - parentLeft;
final int parentTop = getPaddingTop();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
final int width = child.getMeasuredWidth();
final int height = child.getMeasuredHeight();
final int childLeft = parentLeft + (parentContentWidth - width) / 2;
final int childTop;
if (mBaseline != -1 && child.getBaseline() != -1) {
childTop = parentTop + mBaseline - child.getBaseline();
} else {
childTop = parentTop;
}
child.layout(childLeft, childTop, childLeft + width, childTop + height);
}
}
@Override
public int getBaseline() {
View child = getSelectedView();
if (child != null) {
final int childBaseline = child.getBaseline();
return childBaseline >= 0 ? child.getTop() + childBaseline : -1;
}
return -1;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int count = getChildCount();
int maxWidth = 0;
int maxHeight = 0;
int maxChildBaseline = -1;
int maxChildDescent = -1;
int childState = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
measureChild(child, widthMeasureSpec, heightMeasureSpec);
final int baseline = child.getBaseline();
if (baseline != -1) {
maxChildBaseline = Math.max(maxChildBaseline, baseline);
maxChildDescent = Math.max(maxChildDescent, child.getMeasuredHeight() - baseline);
}
maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
childState = View.combineMeasuredStates(childState, child.getMeasuredState());
}
if (maxChildBaseline != -1) {
maxChildDescent = Math.max(maxChildDescent, getPaddingBottom());
maxHeight = Math.max(maxHeight, maxChildBaseline + maxChildDescent);
this.baseline = maxChildBaseline;
}
maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
setMeasuredDimension(
View.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
View.resolveSizeAndState(
maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT));
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
final int count = getChildCount();
final int parentLeft = getPaddingLeft();
final int parentRight = right - left - getPaddingRight();
final int parentContentWidth = parentRight - parentLeft;
final int parentTop = getPaddingTop();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
final int width = child.getMeasuredWidth();
final int height = child.getMeasuredHeight();
final int childLeft = parentLeft + (parentContentWidth - width) / 2;
final int childTop;
if (baseline != -1 && child.getBaseline() != -1) {
childTop = parentTop + baseline - child.getBaseline();
} else {
childTop = parentTop;
}
child.layout(childLeft, childTop, childLeft + width, childTop + height);
}
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int count = getChildCount();
int maxWidth = 0;
int maxHeight = 0;
int maxChildBaseline = -1;
int maxChildDescent = -1;
int childState = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
measureChild(child, widthMeasureSpec, heightMeasureSpec);
final int baseline = child.getBaseline();
if (baseline != -1) {
maxChildBaseline = Math.max(maxChildBaseline, baseline);
maxChildDescent = Math.max(maxChildDescent, child.getMeasuredHeight() - baseline);
}
maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
childState = childState | child.getMeasuredState();
}
if (maxChildBaseline != -1) {
maxChildDescent = Math.max(maxChildDescent, getPaddingBottom());
maxHeight = Math.max(maxHeight, maxChildBaseline + maxChildDescent);
mBaseline = maxChildBaseline;
}
maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
setMeasuredDimension(
View.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
View.resolveSizeAndState(maxHeight, heightMeasureSpec,
childState << MEASURED_HEIGHT_STATE_SHIFT));
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
final int count = getChildCount();
final int parentLeft = getPaddingLeft();
final int parentRight = right - left - getPaddingRight();
final int parentContentWidth = parentRight - parentLeft;
final int parentTop = getPaddingTop();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
final int width = child.getMeasuredWidth();
final int height = child.getMeasuredHeight();
final int childLeft = parentLeft + (parentContentWidth - width) / 2;
final int childTop;
if (mBaseline != -1 && child.getBaseline() != -1) {
childTop = parentTop + mBaseline - child.getBaseline();
} else {
childTop = parentTop;
}
child.layout(childLeft, childTop, childLeft + width, childTop + height);
}
}
@Override
public int getBaseline() {
View child = getSelectedView();
if (child != null) {
final int childBaseline = child.getBaseline();
if(childBaseline < 0)
return -1;
int paddingTop = getPaddingTop();
if(mLabelView != null)
paddingTop += mLabelView.getMeasuredHeight();
int remainHeight = getMeasuredHeight() - paddingTop - getPaddingBottom() - getDividerDrawableHeight();
int verticalGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
switch (verticalGravity) {
case Gravity.TOP:
return paddingTop + childBaseline;
case Gravity.BOTTOM:
return paddingTop + remainHeight - child.getMeasuredHeight() + childBaseline;
default:
return (remainHeight - child.getMeasuredHeight()) / 2 + paddingTop + childBaseline;
}
}
return -1;
}
/**
* Place a single View when the layout direction is horizontal
* ({@link FlexContainer#getFlexDirection()} is either {@link FlexDirection#ROW} or
* {@link FlexDirection#ROW_REVERSE}).
*
* @param view the View to be placed
* @param flexLine the {@link FlexLine} where the View belongs to
* @param left the left position of the View, which the View's margin is already taken
* into account
* @param top the top position of the flex line where the View belongs to. The actual
* View's top position is shifted depending on the flexWrap and alignItems
* attributes
* @param right the right position of the View, which the View's margin is already taken
* into account
* @param bottom the bottom position of the flex line where the View belongs to. The actual
* View's bottom position is shifted depending on the flexWrap and alignItems
* attributes
* @see FlexContainer#getAlignItems()
* @see FlexContainer#setAlignItems(int)
* @see FlexItem#getAlignSelf()
*/
void layoutSingleChildHorizontal(View view, FlexLine flexLine, int left, int top, int right,
int bottom) {
FlexItem flexItem = (FlexItem) view.getLayoutParams();
int alignItems = mFlexContainer.getAlignItems();
if (flexItem.getAlignSelf() != AlignSelf.AUTO) {
// Expecting the values for alignItems and mAlignSelf match except for ALIGN_SELF_AUTO.
// Assigning the mAlignSelf value as alignItems should work.
alignItems = flexItem.getAlignSelf();
}
int crossSize = flexLine.mCrossSize;
switch (alignItems) {
case AlignItems.FLEX_START: // Intentional fall through
case AlignItems.STRETCH:
if (mFlexContainer.getFlexWrap() != FlexWrap.WRAP_REVERSE) {
view.layout(left, top + flexItem.getMarginTop(), right,
bottom + flexItem.getMarginTop());
} else {
view.layout(left, top - flexItem.getMarginBottom(), right,
bottom - flexItem.getMarginBottom());
}
break;
case AlignItems.BASELINE:
if (mFlexContainer.getFlexWrap() != FlexWrap.WRAP_REVERSE) {
int marginTop = flexLine.mMaxBaseline - view.getBaseline();
marginTop = Math.max(marginTop, flexItem.getMarginTop());
view.layout(left, top + marginTop, right, bottom + marginTop);
} else {
int marginBottom = flexLine.mMaxBaseline - view.getMeasuredHeight() + view
.getBaseline();
marginBottom = Math.max(marginBottom, flexItem.getMarginBottom());
view.layout(left, top - marginBottom, right, bottom - marginBottom);
}
break;
case AlignItems.FLEX_END:
if (mFlexContainer.getFlexWrap() != FlexWrap.WRAP_REVERSE) {
view.layout(left,
top + crossSize - view.getMeasuredHeight() - flexItem.getMarginBottom(),
right, top + crossSize - flexItem.getMarginBottom());
} else {
// If the flexWrap == WRAP_REVERSE, the direction of the
// flexEnd is flipped (from top to bottom).
view.layout(left,
top - crossSize + view.getMeasuredHeight() + flexItem.getMarginTop(),
right, bottom - crossSize + view.getMeasuredHeight() + flexItem
.getMarginTop());
}
break;
case AlignItems.CENTER:
int topFromCrossAxis = (crossSize - view.getMeasuredHeight()
+ flexItem.getMarginTop() - flexItem.getMarginBottom()) / 2;
if (mFlexContainer.getFlexWrap() != FlexWrap.WRAP_REVERSE) {
view.layout(left, top + topFromCrossAxis,
right, top + topFromCrossAxis + view.getMeasuredHeight());
} else {
view.layout(left, top - topFromCrossAxis,
right, top - topFromCrossAxis + view.getMeasuredHeight());
}
break;
}
}
/**
* Sub method for {@link #onMeasure(int, int)}, when the main axis direction is horizontal
* (either left to right or right to left).
*
* @param widthMeasureSpec horizontal space requirements as imposed by the parent
* @param heightMeasureSpec vertical space requirements as imposed by the parent
* @see #onMeasure(int, int)
* @see #setFlexDirection(int)
* @see #setFlexWrap(int)
* @see #setAlignItems(int)
* @see #setAlignContent(int)
*/
private void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) {
mFlexLines.clear();
mFlexLinesResult.reset();
mFlexboxHelper
.calculateHorizontalFlexLines(mFlexLinesResult, widthMeasureSpec,
heightMeasureSpec);
mFlexLines = mFlexLinesResult.mFlexLines;
mFlexboxHelper.determineMainSize(widthMeasureSpec, heightMeasureSpec);
// TODO: Consider the case any individual child's mAlignSelf is set to ALIGN_SELF_BASELINE
if (mAlignItems == AlignItems.BASELINE) {
for (FlexLine flexLine : mFlexLines) {
// The largest height value that also take the baseline shift into account
int largestHeightInLine = Integer.MIN_VALUE;
for (int i = 0; i < flexLine.mItemCount; i++) {
int viewIndex = flexLine.mFirstIndex + i;
View child = getReorderedChildAt(viewIndex);
if (child == null || child.getVisibility() == View.GONE) {
continue;
}
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (mFlexWrap != FlexWrap.WRAP_REVERSE) {
int marginTop = flexLine.mMaxBaseline - child.getBaseline();
marginTop = Math.max(marginTop, lp.topMargin);
largestHeightInLine = Math.max(largestHeightInLine,
child.getMeasuredHeight() + marginTop + lp.bottomMargin);
} else {
int marginBottom = flexLine.mMaxBaseline - child.getMeasuredHeight() +
child.getBaseline();
marginBottom = Math.max(marginBottom, lp.bottomMargin);
largestHeightInLine = Math.max(largestHeightInLine,
child.getMeasuredHeight() + lp.topMargin + marginBottom);
}
}
flexLine.mCrossSize = largestHeightInLine;
}
}
mFlexboxHelper.determineCrossSize(widthMeasureSpec, heightMeasureSpec,
getPaddingTop() + getPaddingBottom());
// Now cross size for each flex line is determined.
// Expand the views if alignItems (or mAlignSelf in each child view) is set to stretch
mFlexboxHelper.stretchViews();
setMeasuredDimensionForFlex(mFlexDirection, widthMeasureSpec, heightMeasureSpec,
mFlexLinesResult.mChildState);
}
/**
* Place a single View when the layout direction is horizontal ({@link #mFlexDirection} is
* either {@link #FLEX_DIRECTION_ROW} or {@link #FLEX_DIRECTION_ROW_REVERSE}).
*
* @param view the View to be placed
* @param flexLine the {@link FlexLine} where the View belongs to
* @param flexWrap the flex wrap attribute of this FlexboxLayout
* @param alignItems the align items attribute of this FlexboxLayout
* @param left the left position of the View, which the View's margin is already taken
* into account
* @param top the top position of the flex line where the View belongs to. The actual
* View's top position is shifted depending on the flexWrap and alignItems
* attributes
* @param right the right position of the View, which the View's margin is already taken
* into account
* @param bottom the bottom position of the flex line where the View belongs to. The actual
* View's bottom position is shifted depending on the flexWrap and alignItems
* attributes
* @see #getAlignItems()
* @see #setAlignItems(int)
* @see LayoutParams#alignSelf
*/
private void layoutSingleChildHorizontal(View view, FlexLine flexLine, @FlexWrap int flexWrap,
int alignItems, int left, int top, int right, int bottom) {
LayoutParams lp = (LayoutParams) view.getLayoutParams();
if (lp.alignSelf != LayoutParams.ALIGN_SELF_AUTO) {
// Expecting the values for alignItems and alignSelf match except for ALIGN_SELF_AUTO.
// Assigning the alignSelf value as alignItems should work.
alignItems = lp.alignSelf;
}
int crossSize = flexLine.mCrossSize;
switch (alignItems) {
case ALIGN_ITEMS_FLEX_START: // Intentional fall through
case ALIGN_ITEMS_STRETCH:
if (flexWrap != FLEX_WRAP_WRAP_REVERSE) {
view.layout(left, top + lp.topMargin, right, bottom + lp.topMargin);
} else {
view.layout(left, top - lp.bottomMargin, right, bottom - lp.bottomMargin);
}
break;
case ALIGN_ITEMS_BASELINE:
if (flexWrap != FLEX_WRAP_WRAP_REVERSE) {
int marginTop = flexLine.mMaxBaseline - view.getBaseline();
marginTop = Math.max(marginTop, lp.topMargin);
view.layout(left, top + marginTop, right, bottom + marginTop);
} else {
int marginBottom = flexLine.mMaxBaseline - view.getMeasuredHeight() + view
.getBaseline();
marginBottom = Math.max(marginBottom, lp.bottomMargin);
view.layout(left, top - marginBottom, right, bottom - marginBottom);
}
break;
case ALIGN_ITEMS_FLEX_END:
if (flexWrap != FLEX_WRAP_WRAP_REVERSE) {
view.layout(left,
top + crossSize - view.getMeasuredHeight() - lp.bottomMargin,
right, top + crossSize - lp.bottomMargin);
} else {
// If the flexWrap == FLEX_WRAP_WRAP_REVERSE, the direction of the
// flexEnd is flipped (from top to bottom).
view.layout(left, top - crossSize + view.getMeasuredHeight() + lp.topMargin,
right, bottom - crossSize + view.getMeasuredHeight() + lp.topMargin);
}
break;
case ALIGN_ITEMS_CENTER:
int topFromCrossAxis = (crossSize - view.getMeasuredHeight()) / 2;
if (flexWrap != FLEX_WRAP_WRAP_REVERSE) {
view.layout(left, top + topFromCrossAxis + lp.topMargin - lp.bottomMargin,
right, top + topFromCrossAxis + view.getMeasuredHeight() + lp.topMargin
- lp.bottomMargin);
} else {
view.layout(left, top - topFromCrossAxis + lp.topMargin - lp.bottomMargin,
right, top - topFromCrossAxis + view.getMeasuredHeight() + lp.topMargin
- lp.bottomMargin);
}
break;
}
}
@Override
public int getBaseline() {
if (mBaselineAlignedChildIndex < 0) {
return super.getBaseline();
}
if (getChildCount() <= mBaselineAlignedChildIndex) {
throw new RuntimeException("mBaselineAlignedChildIndex of LinearLayout "
+ "set to an index that is out of bounds.");
}
final View child = getChildAt(mBaselineAlignedChildIndex);
final int childBaseline = child.getBaseline();
if (childBaseline == -1) {
if (mBaselineAlignedChildIndex == 0) {
// this is just the default case, safe to return -1
return -1;
}
// the user picked an index that points to something that doesn't
// know how to calculate its baseline.
throw new RuntimeException("mBaselineAlignedChildIndex of LinearLayout "
+ "points to a View that doesn't know how to get its baseline.");
}
// TODO: This should try to take into account the virtual offsets
// (See getNextLocationOffset and getLocationOffset)
// We should add to childTop:
// sum([getNextLocationOffset(getChildAt(i)) / i < mBaselineAlignedChildIndex])
// and also add:
// getLocationOffset(child)
int childTop = mBaselineChildTop;
if (mOrientation == VERTICAL) {
final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
if (majorGravity != Gravity.TOP) {
switch (majorGravity) {
case Gravity.BOTTOM:
childTop = getBottom() - getTop() - getPaddingBottom() - mTotalLength;
break;
case Gravity.CENTER_VERTICAL:
childTop += ((getBottom() - getTop() - getPaddingTop() - getPaddingBottom()) -
mTotalLength) / 2;
break;
}
}
}
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
return childTop + lp.topMargin + childBaseline;
}