LayoutDirection问题

Android官方提供了 LayoutDirection 的支持,但是很多开发者从来没有用过,甚至完全没有感觉到它的存在。发现的唯一不同之处,可能是多了个 start 和 end ,用起来感觉和left,right没有差别,官方更推荐使用start和end来代替 left,right。但是在看源码的时候,这个东西却经常出来,今天我们就来简单了解一下它到底是什么东西。
我们先来查看一下它的官方定义


        
            
            
            
            
            
            
            
            
        

其实看了之后,也没有什么神秘感的,其实这个就是用来解决不同地区的人的书写习惯的,现代汉语和英语一样都是从左到右书写的,但是还有一些地区书写习惯是从右向左的。这个LayoutDirection就是用来解决这个问题的。官方定义这个属性只有两个值是么是从左到右,要么是从右到左。默认是inherit,也就是继承父View的这个属性,如果都没有设置,那么它的值就是 locale. 最终的结果就是en-US的值也就是LTR,从左到右。现代汉语和英语的书写习惯相同,所以我们平时其实是不需要关心也不需要处理这个属性的。
然后我们再来看下start,end和left,right的区别。其实如果LayoutDirection是LTR的时候,start就相当于left,end和right功能相同,所以对我们来说使用哪个都是一样的。但如果LayoutDirection是RTL的时候,结果就是相反的。start其实是right,end才是left,这个和书写习惯有关。下边给两个配图简要说明下。


LayoutDirection问题_第1张图片
默认的LTR
LayoutDirection问题_第2张图片
RTL的效果

所以为了统一起见,推荐大家使用start和end.

/**
 * A class for defining layout directions. A layout direction can be left-to-right (LTR)
 * or right-to-left (RTL). It can also be inherited (from a parent) or deduced from the default
 * language script of a locale.
 */
public final class LayoutDirection {

    // No instantiation
    private LayoutDirection() {}

    /**
     * An undefined layout direction.
     * @hide
     */
    public static final int UNDEFINED = -1;

    /**
     * Horizontal layout direction is from Left to Right.
     */
    public static final int LTR = 0;

    /**
     * Horizontal layout direction is from Right to Left.
     */
    public static final int RTL = 1;

    /**
     * Horizontal layout direction is inherited.
     */
    public static final int INHERIT = 2;

    /**
     * Horizontal layout direction is deduced from the default language script for the locale.
     */
    public static final int LOCALE = 3;
}

在Java文件中,也就是进行一些常量定义。关键是要查看它的使用。

  /**
         * Retuns the layout direction. Can be either {@link View#LAYOUT_DIRECTION_LTR} or
         * {@link View#LAYOUT_DIRECTION_RTL}.
         *
         * @return the layout direction.
         */
        public int getLayoutDirection() {
            return (mMarginFlags & LAYOUT_DIRECTION_MASK);
        }

        /**
         * Bit  0: layout direction
         * Bit  1: layout direction
         * Bit  2: left margin undefined
         * Bit  3: right margin undefined
         * Bit  4: is RTL compatibility mode
         * Bit  5: need resolution
         *
         * Bit 6 to 7 not used
         *
         * @hide
         */
        @ViewDebug.ExportedProperty(category = "layout", flagMapping = {
                @ViewDebug.FlagToString(mask = LAYOUT_DIRECTION_MASK,
                        equals = LAYOUT_DIRECTION_MASK, name = "LAYOUT_DIRECTION"),
                @ViewDebug.FlagToString(mask = LEFT_MARGIN_UNDEFINED_MASK,
                        equals = LEFT_MARGIN_UNDEFINED_MASK, name = "LEFT_MARGIN_UNDEFINED_MASK"),
                @ViewDebug.FlagToString(mask = RIGHT_MARGIN_UNDEFINED_MASK,
                        equals = RIGHT_MARGIN_UNDEFINED_MASK, name = "RIGHT_MARGIN_UNDEFINED_MASK"),
                @ViewDebug.FlagToString(mask = RTL_COMPATIBILITY_MODE_MASK,
                        equals = RTL_COMPATIBILITY_MODE_MASK, name = "RTL_COMPATIBILITY_MODE_MASK"),
                @ViewDebug.FlagToString(mask = NEED_RESOLUTION_MASK,
                        equals = NEED_RESOLUTION_MASK, name = "NEED_RESOLUTION_MASK")
        }, formatToHexString = true)
        byte mMarginFlags;

        private static final int LAYOUT_DIRECTION_MASK = 0x00000003;
        private static final int LEFT_MARGIN_UNDEFINED_MASK = 0x00000004;
        private static final int RIGHT_MARGIN_UNDEFINED_MASK = 0x00000008;
        private static final int RTL_COMPATIBILITY_MODE_MASK = 0x00000010;
        private static final int NEED_RESOLUTION_MASK = 0x00000020;

内部是通过按位与的操作来判断的,最终来确定它的LayoutDirction。
最后来总结一下,这个LayoutDirection是用来处理左右书写习惯问题的,平时大家不需要关心,当在源码中看到时候,大家只需要知道它会处理成咱们预期的那咱布局方式即可。

你可能感兴趣的:(LayoutDirection问题)