下面列出了android.support.v4.view.ViewCompat#getLayoutDirection ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void draw(Canvas canvas) {
copyBounds(mTmpRect);
canvas.save();
// Layout direction must be obtained from the activity.
final boolean isLayoutRTL = ViewCompat.getLayoutDirection(
mActivity.getWindow().getDecorView()) == ViewCompat.LAYOUT_DIRECTION_RTL;
final int flipRtl = isLayoutRTL ? -1 : 1;
final int width = mTmpRect.width();
canvas.translate(-mOffset * width * mPosition * flipRtl, 0);
// Force auto-mirroring if it's not supported by the platform.
if (isLayoutRTL && !mHasMirroring) {
canvas.translate(width, 0);
canvas.scale(-1, 1);
}
super.draw(canvas);
canvas.restore();
}
@Override
public void draw(Canvas canvas) {
copyBounds(mTmpRect);
canvas.save();
// Layout direction must be obtained from the activity.
final boolean isLayoutRTL = ViewCompat.getLayoutDirection(
mActivity.getWindow().getDecorView()) == ViewCompat.LAYOUT_DIRECTION_RTL;
final int flipRtl = isLayoutRTL ? -1 : 1;
final int width = mTmpRect.width();
canvas.translate(-mOffset * width * mPosition * flipRtl, 0);
// Force auto-mirroring if it's not supported by the platform.
if (isLayoutRTL && !mHasMirroring) {
canvas.translate(width, 0);
canvas.scale(-1, 1);
}
super.draw(canvas);
canvas.restore();
}
public void showHint(int color) {
final int[] screenPos = new int[2];
final Rect displayFrame = new Rect();
getLocationOnScreen(screenPos);
getWindowVisibleDisplayFrame(displayFrame);
final Context context = getContext();
final int width = getWidth();
final int height = getHeight();
final int midy = screenPos[1] + height / 2;
int referenceX = screenPos[0] + width / 2;
if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_LTR) {
final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
referenceX = screenWidth - referenceX; // mirror
}
Toast cheatSheet = Toast
.makeText(context, String.format("#%06X", 0xFFFFFF & color), Toast.LENGTH_SHORT);
if (midy < displayFrame.height()) {
// Show along the top; follow action buttons
cheatSheet.setGravity(Gravity.TOP | GravityCompat.END, referenceX,
screenPos[1] + height - displayFrame.top);
} else {
// Show along the bottom center
cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
}
cheatSheet.show();
}
private Drawable resolveLeftShadow() {
int layoutDirection = ViewCompat.getLayoutDirection(this);
// Prefer shadows defined with start/end gravity over left and right.
if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) {
if (mShadowStart != null) {
// Correct drawable layout direction, if needed.
mirror(mShadowStart, layoutDirection);
return mShadowStart;
}
} else {
if (mShadowEnd != null) {
// Correct drawable layout direction, if needed.
mirror(mShadowEnd, layoutDirection);
return mShadowEnd;
}
}
return mShadowLeft;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view);
Resources resources = context.getResources();
int horizontalPadding = (int) resources.getDimension(R.dimen.whats_new__padding__app_card__horizontal);
int verticalPadding = (int) resources.getDimension(R.dimen.whats_new__padding__app_card__vertical);
int relativePositionInCycle = position % 5;
if (position == 0) {
outRect.set(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
} else if (relativePositionInCycle != 0) {
// The item on the left will have both left and right padding. The item on the right
// will only have padding on the right. This will allow the same amount of padding
// on the left, centre, and right of the grid, rather than double the padding in the
// middle (which would happen if both left and right padding was set for both items).
boolean isLtr = ViewCompat.getLayoutDirection(parent) == ViewCompat.LAYOUT_DIRECTION_LTR;
boolean isAtStart = relativePositionInCycle == 1 || relativePositionInCycle == 3;
int paddingStart = isAtStart ? horizontalPadding : 0;
int paddingLeft = isLtr ? paddingStart : horizontalPadding;
int paddingRight = isLtr ? horizontalPadding : paddingStart;
outRect.set(paddingLeft, 0, paddingRight, verticalPadding);
} else {
outRect.set(horizontalPadding, 0, horizontalPadding, verticalPadding);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int layoutDirection = ViewCompat.getLayoutDirection(this);
boolean isRtl;
switch (mFlexDirection) {
case FlexDirection.ROW:
isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
layoutHorizontal(isRtl, left, top, right, bottom);
break;
case FlexDirection.ROW_REVERSE:
isRtl = layoutDirection != ViewCompat.LAYOUT_DIRECTION_RTL;
layoutHorizontal(isRtl, left, top, right, bottom);
break;
case FlexDirection.COLUMN:
isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
if (mFlexWrap == FlexWrap.WRAP_REVERSE) {
isRtl = !isRtl;
}
layoutVertical(isRtl, false, left, top, right, bottom);
break;
case FlexDirection.COLUMN_REVERSE:
isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
if (mFlexWrap == FlexWrap.WRAP_REVERSE) {
isRtl = !isRtl;
}
layoutVertical(isRtl, true, left, top, right, bottom);
break;
default:
throw new IllegalStateException("Invalid flex direction is set: " + mFlexDirection);
}
}
private boolean calculateIsRtl(CharSequence text) {
final boolean defaultIsRtl = ViewCompat.getLayoutDirection(mView)
== ViewCompat.LAYOUT_DIRECTION_RTL;
return (defaultIsRtl
? TextDirectionHeuristicsCompat.FIRSTSTRONG_RTL
: TextDirectionHeuristicsCompat.FIRSTSTRONG_LTR).isRtl(text, 0, text.length());
}
private Drawable resolveLeftShadow() {
int layoutDirection = ViewCompat.getLayoutDirection(this);
if (layoutDirection == 0) {
if (this.mShadowStart != null) {
mirror(this.mShadowStart, layoutDirection);
return this.mShadowStart;
}
} else if (this.mShadowEnd != null) {
mirror(this.mShadowEnd, layoutDirection);
return this.mShadowEnd;
}
return this.mShadowLeft;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
final ImageButton leftButton;
final ImageButton rightButton;
if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
leftButton = nextButton;
rightButton = prevButton;
} else {
leftButton = prevButton;
rightButton = nextButton;
}
final int width = right - left;
final int height = bottom - top;
dayPickerView.layout(0, 0, width, height);
final SimpleMonthView monthView = (SimpleMonthView) dayPickerView.getChildAt(0);
final int monthHeight = monthView.getMonthHeight();
final int cellWidth = monthView.getCellWidth();
final int edgePadding = monthView.getEdgePadding();
// Vertically center the previous/next buttons within the month
// header, horizontally center within the day cell.
final int leftDW = leftButton.getMeasuredWidth();
final int leftDH = leftButton.getMeasuredHeight();
final int leftIconTop = monthView.getPaddingTop() + (monthHeight - leftDH) / 2;
final int leftIconLeft = edgePadding + (cellWidth - leftDW) / 2;
leftButton.layout(leftIconLeft, leftIconTop, leftIconLeft + leftDW, leftIconTop + leftDH);
final int rightDW = rightButton.getMeasuredWidth();
final int rightDH = rightButton.getMeasuredHeight();
final int rightIconTop = monthView.getPaddingTop() + (monthHeight - rightDH) / 2;
final int rightIconRight = width - edgePadding - (cellWidth - rightDW) / 2 - 2;
rightButton.layout(rightIconRight - rightDW, rightIconTop,
rightIconRight, rightIconTop + rightDH);
}
@Override
public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) {
final int parentLeft = getPaddingLeft();
final int parentTop = getPaddingTop();
final int parentRight = getWidth() - getPaddingRight();
final int parentBottom = getHeight() - getPaddingBottom();
final int childLeft = child.getLeft() + rect.left;
final int childTop = child.getTop() + rect.top;
// final int childLeft = child.getLeft() + rect.left - child.getScrollX();
// final int childTop = child.getTop() + rect.top - child.getScrollY();
final int childRight = childLeft + rect.width();
final int childBottom = childTop + rect.height();
final int offScreenLeft = Math.min(0, childLeft - parentLeft - mSelectedItemOffsetStart);
final int offScreenTop = Math.min(0, childTop - parentTop - mSelectedItemOffsetStart);
final int offScreenRight = Math.max(0, childRight - parentRight + mSelectedItemOffsetEnd);
final int offScreenBottom = Math.max(0, childBottom - parentBottom + mSelectedItemOffsetEnd);
final boolean canScrollHorizontal = getLayoutManager().canScrollHorizontally();
final boolean canScrollVertical = getLayoutManager().canScrollVertically();
// Favor the "start" layout direction over the end when bringing one side or the other
// of a large rect into view. If we decide to bring in end because start is already
// visible, limit the scroll such that start won't go out of bounds.
final int dx;
if (canScrollHorizontal) {
if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
dx = offScreenRight != 0 ? offScreenRight
: Math.max(offScreenLeft, childRight - parentRight);
} else {
dx = offScreenLeft != 0 ? offScreenLeft
: Math.min(childLeft - parentLeft, offScreenRight);
}
} else {
dx = 0;
}
// Favor bringing the top into view over the bottom. If top is already visible and
// we should scroll to make bottom visible, make sure top does not go out of bounds.
final int dy;
if (canScrollVertical) {
dy = offScreenTop != 0 ? offScreenTop : Math.min(childTop - parentTop, offScreenBottom);
} else {
dy = 0;
}
if (cannotScrollForwardOrBackward(isVertical() ? dy : dx)) {
offset = -1;
} else {
offset = isVertical() ? dy : dx;
if (dx != 0 || dy != 0) {
if (immediate) {
scrollBy(dx, dy);
} else {
smoothScrollBy(dx, dy);
}
return true;
}
}
// 重绘是为了选中item置顶,具体请参考getChildDrawingOrder方法
postInvalidate();
return false;
}
static boolean isLayoutRtl(View v) {
return ViewCompat.getLayoutDirection(v) == ViewCompat.LAYOUT_DIRECTION_RTL;
}
@Override
protected void onDraw(Canvas canvas) {
if (mDividerDrawableVertical == null && mDividerDrawableHorizontal == null) {
return;
}
if (mShowDividerHorizontal == SHOW_DIVIDER_NONE
&& mShowDividerVertical == SHOW_DIVIDER_NONE) {
return;
}
int layoutDirection = ViewCompat.getLayoutDirection(this);
boolean isRtl;
boolean fromBottomToTop = false;
switch (mFlexDirection) {
case FlexDirection.ROW:
isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
if (mFlexWrap == FlexWrap.WRAP_REVERSE) {
fromBottomToTop = true;
}
drawDividersHorizontal(canvas, isRtl, fromBottomToTop);
break;
case FlexDirection.ROW_REVERSE:
isRtl = layoutDirection != ViewCompat.LAYOUT_DIRECTION_RTL;
if (mFlexWrap == FlexWrap.WRAP_REVERSE) {
fromBottomToTop = true;
}
drawDividersHorizontal(canvas, isRtl, fromBottomToTop);
break;
case FlexDirection.COLUMN:
isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
if (mFlexWrap == FlexWrap.WRAP_REVERSE) {
isRtl = !isRtl;
}
drawDividersVertical(canvas, isRtl, false);
break;
case FlexDirection.COLUMN_REVERSE:
isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
if (mFlexWrap == FlexWrap.WRAP_REVERSE) {
isRtl = !isRtl;
}
drawDividersVertical(canvas, isRtl, true);
break;
}
}
@Override
boolean isLayoutRtl() {
return ViewCompat.getLayoutDirection(mActivity.getWindow().getDecorView())
== ViewCompat.LAYOUT_DIRECTION_RTL;
}
public boolean isLayoutRtl() {
return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
}
private boolean isLayoutRTL() {
return ViewCompat.getLayoutDirection(mRecyclerView) == ViewCompat.LAYOUT_DIRECTION_RTL;
}
@Override
protected void onDraw(Canvas canvas) {
if (mDividerDrawableVertical == null && mDividerDrawableHorizontal == null) {
return;
}
if (mShowDividerHorizontal == SHOW_DIVIDER_NONE
&& mShowDividerVertical == SHOW_DIVIDER_NONE) {
return;
}
int layoutDirection = ViewCompat.getLayoutDirection(this);
boolean isRtl;
boolean fromBottomToTop = false;
switch (mFlexDirection) {
case FLEX_DIRECTION_ROW:
isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
if (mFlexWrap == FLEX_WRAP_WRAP_REVERSE) {
fromBottomToTop = true;
}
drawDividersHorizontal(canvas, isRtl, fromBottomToTop);
break;
case FLEX_DIRECTION_ROW_REVERSE:
isRtl = layoutDirection != ViewCompat.LAYOUT_DIRECTION_RTL;
if (mFlexWrap == FLEX_WRAP_WRAP_REVERSE) {
fromBottomToTop = true;
}
drawDividersHorizontal(canvas, isRtl, fromBottomToTop);
break;
case FLEX_DIRECTION_COLUMN:
isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
if (mFlexWrap == FLEX_WRAP_WRAP_REVERSE) {
isRtl = !isRtl;
}
fromBottomToTop = false;
drawDividersVertical(canvas, isRtl, fromBottomToTop);
break;
case FLEX_DIRECTION_COLUMN_REVERSE:
isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
if (mFlexWrap == FLEX_WRAP_WRAP_REVERSE) {
isRtl = !isRtl;
}
fromBottomToTop = true;
drawDividersVertical(canvas, isRtl, fromBottomToTop);
break;
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
// Update the collapsed bounds by getting it's transformed bounds. This needs to be done
// before the children are offset below
if (mCollapsingTitleEnabled && mDummyView != null) {
// We only draw the title if the dummy view is being displayed (Toolbar removes
// views if there is no space)
mDrawCollapsingTitle = ViewCompat.isAttachedToWindow(mDummyView) && mDummyView.getVisibility() == VISIBLE;
if (mDrawCollapsingTitle) {
final boolean isRtl = ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
// Update the collapsed bounds
int bottomOffset = 0;
if (mToolbarDirectChild != null && mToolbarDirectChild != this) {
final LayoutParams lp = (LayoutParams) mToolbarDirectChild.getLayoutParams();
bottomOffset = lp.bottomMargin;
}
ViewGroupUtils.getDescendantRect(this, mDummyView, mTmpRect);
mCollapsingTextHelper.setCollapsedBounds(
mTmpRect.left + (isRtl ? mToolbar.getTitleMarginEnd() : mToolbar.getTitleMarginStart()),
bottom + mToolbar.getTitleMarginTop() - mTmpRect.height() - bottomOffset,
mTmpRect.right + (isRtl ? mToolbar.getTitleMarginStart() : mToolbar.getTitleMarginEnd()),
bottom - bottomOffset - mToolbar.getTitleMarginBottom());
// Update the expanded bounds
mCollapsingTextHelper.setExpandedBounds(
isRtl ? mExpandedMarginEnd : mExpandedMarginStart,
mTmpRect.bottom + mExpandedMarginTop,
right - left - (isRtl ? mExpandedMarginStart : mExpandedMarginEnd),
bottom - top - mExpandedMarginBottom);
// Now recalculate using the new bounds
mCollapsingTextHelper.recalculate();
}
}
// Update our child view offset helpers
for (int i = 0, z = getChildCount(); i < z; i++) {
final View child = getChildAt(i);
if (mLastInsets != null && !ViewCompat.getFitsSystemWindows(child)) {
final int insetTop = mLastInsets.getSystemWindowInsetTop();
if (child.getTop() < insetTop) {
// If the child isn't set to fit system windows but is drawing within the inset
// offset it down
ViewCompat.offsetTopAndBottom(child, insetTop);
}
}
getViewOffsetHelper(child).onViewLayout();
}
// Finally, set our minimum height to enable proper AppBarLayout collapsing
if (mToolbar != null) {
if (mCollapsingTitleEnabled && TextUtils.isEmpty(mCollapsingTextHelper.getText())) {
// If we do not currently have a title, try and grab it from the Toolbar
mCollapsingTextHelper.setText(mToolbar.getTitle());
}
if (mToolbarDirectChild == null || mToolbarDirectChild == this) {
setMinimumHeight(getHeightWithMargins(mToolbar));
} else {
setMinimumHeight(getHeightWithMargins(mToolbarDirectChild));
}
}
}
public int getDrawerLockMode(int edgeGravity) {
int layoutDirection = ViewCompat.getLayoutDirection(this);
switch (edgeGravity) {
case 3:
if (this.mLockModeLeft != 3) {
return this.mLockModeLeft;
}
int leftLockMode = layoutDirection == 0 ? this.mLockModeStart : this.mLockModeEnd;
if (leftLockMode != 3) {
return leftLockMode;
}
break;
case 5:
if (this.mLockModeRight != 3) {
return this.mLockModeRight;
}
int rightLockMode = layoutDirection == 0 ? this.mLockModeEnd : this.mLockModeStart;
if (rightLockMode != 3) {
return rightLockMode;
}
break;
case GravityCompat.START /*8388611*/:
if (this.mLockModeStart != 3) {
return this.mLockModeStart;
}
int startLockMode = layoutDirection == 0 ? this.mLockModeLeft : this.mLockModeRight;
if (startLockMode != 3) {
return startLockMode;
}
break;
case GravityCompat.END /*8388613*/:
if (this.mLockModeEnd != 3) {
return this.mLockModeEnd;
}
int endLockMode = layoutDirection == 0 ? this.mLockModeRight : this.mLockModeLeft;
if (endLockMode != 3) {
return endLockMode;
}
break;
}
return 0;
}
private boolean isLayoutRtlSupport() {
return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
}
public boolean isRtl() {
return (ViewCompat.getLayoutDirection(this) == LAYOUT_DIRECTION_RTL) && mMirrorForRtl;
}