下面列出了android.support.v4.view.ViewCompat#LAYOUT_DIRECTION_LTR 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Replaces a movement direction with its relative version by taking layout direction into
* account.
*
* @param flags The flag value that include any number of movement flags.
* @param layoutDirection The layout direction of the View. Can be obtained from
* {@link ViewCompat#getLayoutDirection(android.view.View)}.
* @return Updated flags which uses relative flags ({@link #START}, {@link #END}) instead
* of {@link #LEFT}, {@link #RIGHT}.
* @see #convertToAbsoluteDirection(int, int)
*/
public static int convertToRelativeDirection(int flags, int layoutDirection) {
int masked = flags & ABS_HORIZONTAL_DIR_FLAGS;
if (masked == 0) {
return flags; // does not have any abs flags, good.
}
flags &= ~masked; //remove left / right.
if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) {
// no change. just OR with 2 bits shifted mask and return
flags |= masked << 2; // START is 2 bits after LEFT, END is 2 bits after RIGHT.
return flags;
} else {
// add RIGHT flag as START
flags |= ((masked << 1) & ~ABS_HORIZONTAL_DIR_FLAGS);
// first clean RIGHT bit then add LEFT flag as END
flags |= ((masked << 1) & ABS_HORIZONTAL_DIR_FLAGS) << 2;
}
return flags;
}
public static int convertToRelativeDirection(int flags, int layoutDirection) {
int masked = flags & ABS_HORIZONTAL_DIR_FLAGS;
if (masked == 0) {
return flags;// does not have any abs flags, good.
}
flags &= ~masked; //remove left / right.
if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) {
// no change. just OR with 2 bits shifted mask and return
flags |= masked << 2; // START is 2 bits after LEFT, END is 2 bits after RIGHT.
return flags;
} else {
// add RIGHT flag as START
flags |= ((masked << 1) & ~ABS_HORIZONTAL_DIR_FLAGS);
// first clean RIGHT bit then add LEFT flag as END
flags |= ((masked << 1) & ABS_HORIZONTAL_DIR_FLAGS) << 2;
}
return flags;
}
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
int masked = flags & RELATIVE_DIR_FLAGS;
if (masked == 0) {
return flags;// does not have any relative flags, good.
}
flags &= ~masked; //remove start / end
if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) {
// no change. just OR with 2 bits shifted mask and return
flags |= masked >> 2; // START is 2 bits after LEFT, END is 2 bits after RIGHT.
return flags;
} else {
// add START flag as RIGHT
flags |= ((masked >> 1) & ~RELATIVE_DIR_FLAGS);
// first clean start bit then add END flag as LEFT
flags |= ((masked >> 1) & RELATIVE_DIR_FLAGS) >> 2;
}
return flags;
}
/**
* Replaces a movement direction with its relative version by taking layout direction into
* account.
*
* @param flags The flag value that include any number of movement flags.
* @param layoutDirection The layout direction of the View. Can be obtained from
* {@link ViewCompat#getLayoutDirection(android.view.View)}.
* @return Updated flags which uses relative flags ({@link #START}, {@link #END}) instead
* of {@link #LEFT}, {@link #RIGHT}.
* @see #convertToAbsoluteDirection(int, int)
*/
public static int convertToRelativeDirection(int flags, int layoutDirection) {
int masked = flags & ABS_HORIZONTAL_DIR_FLAGS;
if (masked == 0) {
return flags; // does not have any abs flags, good.
}
flags &= ~masked; //remove left / right.
if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) {
// no change. just OR with 2 bits shifted mask and return
flags |= masked << 2; // START is 2 bits after LEFT, END is 2 bits after RIGHT.
return flags;
} else {
// add RIGHT flag as START
flags |= ((masked << 1) & ~ABS_HORIZONTAL_DIR_FLAGS);
// first clean RIGHT bit then add LEFT flag as END
flags |= ((masked << 1) & ABS_HORIZONTAL_DIR_FLAGS) << 2;
}
return flags;
}
@Override
public void onRtlPropertiesChanged(int layoutDirection) {
super.onRtlPropertiesChanged(layoutDirection);
int viewCompatLayoutDirection = layoutDirection == View.LAYOUT_DIRECTION_RTL ?
ViewCompat.LAYOUT_DIRECTION_RTL :
ViewCompat.LAYOUT_DIRECTION_LTR;
if (viewCompatLayoutDirection != mLayoutDirection) {
PagerAdapter adapter = super.getAdapter();
int position = 0;
if (adapter != null) {
position = getCurrentItem();
}
mLayoutDirection = viewCompatLayoutDirection;
if (adapter != null) {
adapter.notifyDataSetChanged();
setCurrentItem(position);
}
}
}
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;
}
private Drawable resolveRightShadow() {
int layoutDirection = ViewCompat.getLayoutDirection(this);
if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) {
if (mShadowEnd != null) {
// Correct drawable layout direction, if needed.
mirror(mShadowEnd, layoutDirection);
return mShadowEnd;
}
} else {
if (mShadowStart != null) {
// Correct drawable layout direction, if needed.
mirror(mShadowStart, layoutDirection);
return mShadowStart;
}
}
return mShadowRight;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
Resources r = context.getResources();
int horizontalPadding = (int) r.getDimension(R.dimen.category_preview__app_list__padding__horizontal);
int horizontalPaddingFirst = (int) r.getDimension(
R.dimen.category_preview__app_list__padding__horizontal__first);
int horizontalPaddingLast = (int) r.getDimension(
R.dimen.category_preview__app_list__padding__horizontal__last);
boolean isLtr = ViewCompat.getLayoutDirection(parent) == ViewCompat.LAYOUT_DIRECTION_LTR;
int itemPosition = parent.getChildLayoutPosition(view);
boolean first = itemPosition == 0;
boolean end = itemPosition == categoryItemCount - 1;
// Leave this "paddingEnd" local variable here for clarity when converting from
// left/right to start/end for RTL friendly layout.
// noinspection UnnecessaryLocalVariable
int paddingEnd = end ? horizontalPaddingLast : horizontalPadding;
int paddingStart = first ? horizontalPaddingFirst : horizontalPadding;
int paddingLeft = isLtr ? paddingStart : paddingEnd;
int paddingRight = isLtr ? paddingEnd : paddingStart;
outRect.set(paddingLeft, 0, paddingRight, 0);
}
@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);
}
}
/**
* Show a toast message with the hex color code below the view.
*/
public void showHint() {
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
}
StringBuilder hint = new StringBuilder("#");
if (Color.alpha(color) != 255) {
hint.append(Integer.toHexString(color).toUpperCase(Locale.ENGLISH));
} else {
hint.append(String.format("%06X", 0xFFFFFF & color).toUpperCase(Locale.ENGLISH));
}
Toast cheatSheet = Toast.makeText(context, hint.toString(), 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();
}
/**
* Return the layout direction for a given Locale
*
* @param locale the Locale for which we want the layout direction. Can be null.
* @return the layout direction. This may be one of:
* {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
* {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be updated when vertical scripts will be supported
*/
public static int getLayoutDirectionFromLocale(Locale locale) {
if (locale != null && !locale.equals(ROOT)) {
final String scriptSubtag = ICUCompat.getScript(
ICUCompat.addLikelySubtags(locale.toString()));
if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale);
if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
return ViewCompat.LAYOUT_DIRECTION_RTL;
}
}
return ViewCompat.LAYOUT_DIRECTION_LTR;
}
/**
* Return the layout direction for a given Locale
*
* @param locale the Locale for which we want the layout direction. Can be null.
* @return the layout direction. This may be one of:
* {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
* {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be updated when vertical scripts will be supported
*/
public static int getLayoutDirectionFromLocale(Locale locale) {
if (locale != null && !locale.equals(ROOT)) {
final String scriptSubtag = ICUCompat.getScript(
ICUCompat.addLikelySubtags(locale.toString()));
if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale);
if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
return ViewCompat.LAYOUT_DIRECTION_RTL;
}
}
return ViewCompat.LAYOUT_DIRECTION_LTR;
}
/**
* Return the layout direction for a given Locale
*
* @param locale the Locale for which we want the layout direction. Can be null.
* @return the layout direction. This may be one of:
* {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
* {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be updated when vertical scripts will be supported
*/
public static int getLayoutDirectionFromLocale(Locale locale) {
if (locale != null && !locale.equals(ROOT)) {
final String scriptSubtag = ICUCompat.getScript(
ICUCompat.addLikelySubtags(locale.toString()));
if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale);
if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
return ViewCompat.LAYOUT_DIRECTION_RTL;
}
}
return ViewCompat.LAYOUT_DIRECTION_LTR;
}
/**
* Return the layout direction for a given Locale
*
* @param locale the Locale for which we want the layout direction. Can be null.
* @return the layout direction. This may be one of:
* {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
* {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be updated when vertical scripts will be supported
*/
public static int getLayoutDirectionFromLocale(@Nullable Locale locale) {
if (locale != null && !locale.equals(ROOT)) {
final String scriptSubtag = ICUCompat.getScript(
ICUCompat.addLikelySubtags(locale.toString()));
if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale);
if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
return ViewCompat.LAYOUT_DIRECTION_RTL;
}
}
return ViewCompat.LAYOUT_DIRECTION_LTR;
}
/**
* Return the layout direction for a given Locale
*
* @param locale the Locale for which we want the layout direction. Can be null.
* @return the layout direction. This may be one of:
* {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
* {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be updated when vertical scripts will be supported
*/
public static int getLayoutDirectionFromLocale(Locale locale) {
if (locale != null && !locale.equals(ROOT)) {
final String scriptSubtag = ICUCompat.getScript(
ICUCompat.addLikelySubtags(locale.toString()));
if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale);
if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
return ViewCompat.LAYOUT_DIRECTION_RTL;
}
}
return ViewCompat.LAYOUT_DIRECTION_LTR;
}
/**
* Check the lock mode of the drawer with the given gravity.
*
* @param edgeGravity Gravity of the drawer to check
* @return one of {@link #LOCK_MODE_UNLOCKED}, {@link #LOCK_MODE_LOCKED_CLOSED} or
* {@link #LOCK_MODE_LOCKED_OPEN}.
*/
@LockMode
public int getDrawerLockMode(@EdgeGravity int edgeGravity) {
int layoutDirection = ViewCompat.getLayoutDirection(this);
switch (edgeGravity) {
case Gravity.LEFT:
if (mLockModeLeft != LOCK_MODE_UNDEFINED) {
return mLockModeLeft;
}
int leftLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) ?
mLockModeStart : mLockModeEnd;
if (leftLockMode != LOCK_MODE_UNDEFINED) {
return leftLockMode;
}
break;
case Gravity.RIGHT:
if (mLockModeRight != LOCK_MODE_UNDEFINED) {
return mLockModeRight;
}
int rightLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) ?
mLockModeEnd : mLockModeStart;
if (rightLockMode != LOCK_MODE_UNDEFINED) {
return rightLockMode;
}
break;
case GravityCompat.START:
if (mLockModeStart != LOCK_MODE_UNDEFINED) {
return mLockModeStart;
}
int startLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) ?
mLockModeLeft : mLockModeRight;
if (startLockMode != LOCK_MODE_UNDEFINED) {
return startLockMode;
}
break;
case GravityCompat.END:
if (mLockModeEnd != LOCK_MODE_UNDEFINED) {
return mLockModeEnd;
}
int endLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) ?
mLockModeRight : mLockModeLeft;
if (endLockMode != LOCK_MODE_UNDEFINED) {
return endLockMode;
}
break;
}
return LOCK_MODE_UNLOCKED;
}
/**
* Fallback algorithm to detect the locale direction. Rely on the fist char of the
* localized locale name. This will not work if the localized locale name is in English
* (this is the case for ICU 4.4 and "Urdu" script)
*
* @param locale
* @return the layout direction. This may be one of:
* {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
* {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be updated when vertical scripts will be supported
*/
private static int getLayoutDirectionFromFirstChar(Locale locale) {
switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
return ViewCompat.LAYOUT_DIRECTION_RTL;
case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
default:
return ViewCompat.LAYOUT_DIRECTION_LTR;
}
}
/**
* Fallback algorithm to detect the locale direction. Rely on the fist char of the
* localized locale name. This will not work if the localized locale name is in English
* (this is the case for ICU 4.4 and "Urdu" script)
*
* @param locale
* @return the layout direction. This may be one of:
* {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
* {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be updated when vertical scripts will be supported
*/
private static int getLayoutDirectionFromFirstChar(Locale locale) {
switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
return ViewCompat.LAYOUT_DIRECTION_RTL;
case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
default:
return ViewCompat.LAYOUT_DIRECTION_LTR;
}
}
/**
* Fallback algorithm to detect the locale direction. Rely on the fist char of the
* localized locale name. This will not work if the localized locale name is in English
* (this is the case for ICU 4.4 and "Urdu" script)
*
* @param locale
* @return the layout direction. This may be one of:
* {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
* {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be updated when vertical scripts will be supported
*/
private static int getLayoutDirectionFromFirstChar(Locale locale) {
switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
return ViewCompat.LAYOUT_DIRECTION_RTL;
case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
default:
return ViewCompat.LAYOUT_DIRECTION_LTR;
}
}
/**
* Fallback algorithm to detect the locale direction. Rely on the fist char of the
* localized locale name. This will not work if the localized locale name is in English
* (this is the case for ICU 4.4 and "Urdu" script)
*
* @param locale
* @return the layout direction. This may be one of:
* {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
* {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be updated when vertical scripts will be supported
*/
private static int getLayoutDirectionFromFirstChar(Locale locale) {
switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
return ViewCompat.LAYOUT_DIRECTION_RTL;
case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
default:
return ViewCompat.LAYOUT_DIRECTION_LTR;
}
}