MarginLayoutParamsCompat.java revision c5847d13e40f5d52459f5c0dab32dc08f1a9a683
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18package android.support.v4.view;
19
20import android.os.Build;
21import android.view.ViewGroup;
22
23/**
24 * Helper for accessing API features in
25 * {@link android.view.ViewGroup.MarginLayoutParams MarginLayoutParams} added after API 4.
26 */
27public final class MarginLayoutParamsCompat {
28    interface MarginLayoutParamsCompatImpl {
29        int getMarginStart(ViewGroup.MarginLayoutParams lp);
30        int getMarginEnd(ViewGroup.MarginLayoutParams lp);
31        void setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart);
32        void setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd);
33        boolean isMarginRelative(ViewGroup.MarginLayoutParams lp);
34        int getLayoutDirection(ViewGroup.MarginLayoutParams lp);
35        void setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection);
36        void resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection);
37    }
38
39    static class MarginLayoutParamsCompatImplBase implements MarginLayoutParamsCompatImpl {
40
41        @Override
42        public int getMarginStart(ViewGroup.MarginLayoutParams lp) {
43            return lp.leftMargin;
44        }
45
46        @Override
47        public int getMarginEnd(ViewGroup.MarginLayoutParams lp) {
48            return lp.rightMargin;
49        }
50
51        @Override
52        public void setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart) {
53            lp.leftMargin = marginStart;
54        }
55
56        @Override
57        public void setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd) {
58            lp.rightMargin = marginEnd;
59        }
60
61        @Override
62        public boolean isMarginRelative(ViewGroup.MarginLayoutParams lp) {
63            return false;
64        }
65
66        @Override
67        public int getLayoutDirection(ViewGroup.MarginLayoutParams lp) {
68            return ViewCompat.LAYOUT_DIRECTION_LTR;
69        }
70
71        @Override
72        public void setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection) {
73            // No-op
74        }
75
76        @Override
77        public void resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection) {
78            // No-op
79        }
80    }
81
82    static class MarginLayoutParamsCompatImplJbMr1 implements MarginLayoutParamsCompatImpl {
83
84        @Override
85        public int getMarginStart(ViewGroup.MarginLayoutParams lp) {
86            return MarginLayoutParamsCompatJellybeanMr1.getMarginStart(lp);
87        }
88
89        @Override
90        public int getMarginEnd(ViewGroup.MarginLayoutParams lp) {
91            return MarginLayoutParamsCompatJellybeanMr1.getMarginEnd(lp);
92        }
93
94        @Override
95        public void setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart) {
96            MarginLayoutParamsCompatJellybeanMr1.setMarginStart(lp, marginStart);
97        }
98
99        @Override
100        public void setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd) {
101            MarginLayoutParamsCompatJellybeanMr1.setMarginEnd(lp, marginEnd);
102        }
103
104        @Override
105        public boolean isMarginRelative(ViewGroup.MarginLayoutParams lp) {
106            return MarginLayoutParamsCompatJellybeanMr1.isMarginRelative(lp);
107        }
108
109        @Override
110        public int getLayoutDirection(ViewGroup.MarginLayoutParams lp) {
111            return MarginLayoutParamsCompatJellybeanMr1.getLayoutDirection(lp);
112        }
113
114        @Override
115        public void setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection) {
116            MarginLayoutParamsCompatJellybeanMr1.setLayoutDirection(lp, layoutDirection);
117        }
118
119        @Override
120        public void resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection) {
121            MarginLayoutParamsCompatJellybeanMr1.resolveLayoutDirection(lp, layoutDirection);
122        }
123    }
124
125    static final MarginLayoutParamsCompatImpl IMPL;
126    static {
127        final int version = Build.VERSION.SDK_INT;
128        if (version >= 17) { // jb-mr1
129            IMPL = new MarginLayoutParamsCompatImplJbMr1();
130        } else {
131            IMPL = new MarginLayoutParamsCompatImplBase();
132        }
133    }
134
135    /**
136     * Get the relative starting margin that was set.
137     *
138     * <p>On platform versions supporting bidirectional text and layouts
139     * this value will be resolved into the LayoutParams object's left or right
140     * margin as appropriate when the associated View is attached to a window
141     * or when the layout direction of that view changes.</p>
142     *
143     * @param lp LayoutParams to query
144     * @return the margin along the starting edge in pixels
145     */
146    public static int getMarginStart(ViewGroup.MarginLayoutParams lp) {
147        return IMPL.getMarginStart(lp);
148    }
149
150    /**
151     * Get the relative ending margin that was set.
152     *
153     * <p>On platform versions supporting bidirectional text and layouts
154     * this value will be resolved into the LayoutParams object's left or right
155     * margin as appropriate when the associated View is attached to a window
156     * or when the layout direction of that view changes.</p>
157     *
158     * @param lp LayoutParams to query
159     * @return the margin along the ending edge in pixels
160     */
161    public static int getMarginEnd(ViewGroup.MarginLayoutParams lp) {
162        return IMPL.getMarginEnd(lp);
163    }
164
165    /**
166     * Set the relative start margin.
167     *
168     * <p>On platform versions supporting bidirectional text and layouts
169     * this value will be resolved into the LayoutParams object's left or right
170     * margin as appropriate when the associated View is attached to a window
171     * or when the layout direction of that view changes.</p>
172     *
173     * @param lp LayoutParams to query
174     * @param marginStart the desired start margin in pixels
175     */
176    public static void setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart) {
177        IMPL.setMarginStart(lp, marginStart);
178    }
179
180    /**
181     * Set the relative end margin.
182     *
183     * <p>On platform versions supporting bidirectional text and layouts
184     * this value will be resolved into the LayoutParams object's left or right
185     * margin as appropriate when the associated View is attached to a window
186     * or when the layout direction of that view changes.</p>
187     *
188     * @param lp LayoutParams to query
189     * @param marginEnd the desired end margin in pixels
190     */
191    public static void setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd) {
192        IMPL.setMarginEnd(lp, marginEnd);
193    }
194
195    /**
196     * Check if margins are relative.
197     *
198     * @return true if either marginStart or marginEnd has been set.
199     */
200    public static boolean isMarginRelative(ViewGroup.MarginLayoutParams lp) {
201        return IMPL.isMarginRelative(lp);
202    }
203
204    /**
205     * Returns the layout direction. Can be either {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
206     * {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
207     *
208     * @return the layout direction.
209     */
210    public static int getLayoutDirection(ViewGroup.MarginLayoutParams lp) {
211        int result = IMPL.getLayoutDirection(lp);
212        if ((result != ViewCompat.LAYOUT_DIRECTION_LTR)
213                && (result != ViewCompat.LAYOUT_DIRECTION_RTL)) {
214            // This can happen on older platform releases where the default (unset) layout direction
215            // is -1
216            result = ViewCompat.LAYOUT_DIRECTION_LTR;
217        }
218        return result;
219    }
220
221    /**
222     * Set the layout direction.
223     *
224     * @param layoutDirection the layout direction.
225     *        Should be either {@link ViewCompat#LAYOUT_DIRECTION_LTR}
226     *                     or {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
227     */
228    public static void setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection) {
229        IMPL.setLayoutDirection(lp, layoutDirection);
230    }
231
232    /**
233     * This will be called by {@link android.view.View#requestLayout()}. Left and Right margins
234     * may be overridden depending on layout direction.
235     */
236    public static void resolveLayoutDirection(ViewGroup.MarginLayoutParams lp,
237            int layoutDirection) {
238        IMPL.resolveLayoutDirection(lp, layoutDirection);
239    }
240
241    private MarginLayoutParamsCompat() {}
242}
243