• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 package com.android.settings.widget;
18 
19 import android.content.Context;
20 import android.os.Parcelable;
21 import android.support.v4.view.ViewPager;
22 import android.text.TextUtils;
23 import android.util.AttributeSet;
24 import android.view.View;
25 import android.os.Parcel;
26 
27 import java.util.Locale;
28 
29 /**
30  * A {@link ViewPager} that's aware of RTL changes when used with FragmentPagerAdapter.
31  */
32 public final class RtlCompatibleViewPager extends ViewPager {
33 
34     /**
35      * Callback interface for responding to changing state of the selected page.
36      * Positions supplied will always be the logical position in the adapter -
37      * that is, the 0 index corresponds to the left-most page in LTR and the
38      * right-most page in RTL.
39      */
40 
RtlCompatibleViewPager(Context context)41     public RtlCompatibleViewPager(Context context) {
42         this(context, null /* attrs */);
43     }
44 
RtlCompatibleViewPager(Context context, AttributeSet attrs)45     public RtlCompatibleViewPager(Context context, AttributeSet attrs) {
46         super(context, attrs);
47     }
48 
49     @Override
getCurrentItem()50     public int getCurrentItem() {
51         return getRtlAwareIndex(super.getCurrentItem());
52     }
53 
54     @Override
setCurrentItem(int item)55     public void setCurrentItem(int item) {
56         super.setCurrentItem(getRtlAwareIndex(item));
57     }
58 
59     @Override
onSaveInstanceState()60     public Parcelable onSaveInstanceState() {
61         Parcelable parcelable = super.onSaveInstanceState();
62 
63         RtlSavedState rtlSavedState = new RtlSavedState(parcelable);
64         rtlSavedState.position = getCurrentItem();
65         return rtlSavedState;
66     }
67 
68     @Override
onRestoreInstanceState(Parcelable state)69     public void onRestoreInstanceState(Parcelable state) {
70         RtlSavedState rtlSavedState = (RtlSavedState) state;
71         super.onRestoreInstanceState(rtlSavedState.getSuperState());
72 
73         setCurrentItem(rtlSavedState.position);
74     }
75 
76     /**
77      * Get a "RTL friendly" index. If the locale is LTR, the index is returned as is.
78      * Otherwise it's transformed so view pager can render views using the new index for RTL. For
79      * example, the second view will be rendered to the left of first view.
80      *
81      * @param index The logical index.
82      */
getRtlAwareIndex(int index)83     public int getRtlAwareIndex(int index) {
84         // Using TextUtils rather than View.getLayoutDirection() because LayoutDirection is not
85         // defined until onMeasure, and this is called before then.
86         if (TextUtils.getLayoutDirectionFromLocale(Locale.getDefault())
87                 == View.LAYOUT_DIRECTION_RTL) {
88             return getAdapter().getCount() - index - 1;
89         }
90         return index;
91     }
92 
93     static class RtlSavedState extends BaseSavedState {
94         int position;
95 
RtlSavedState(Parcelable superState)96         public RtlSavedState(Parcelable superState) {
97             super(superState);
98         }
99 
RtlSavedState(Parcel in, ClassLoader loader)100         private RtlSavedState(Parcel in, ClassLoader loader) {
101             super(in, loader);
102             position = in.readInt();
103         }
104 
105         @Override
writeToParcel(Parcel out, int flags)106         public void writeToParcel(Parcel out, int flags) {
107             super.writeToParcel(out, flags);
108             out.writeInt(position);
109         }
110 
111         public static final Parcelable.ClassLoaderCreator<RtlSavedState> CREATOR
112                 = new Parcelable.ClassLoaderCreator<RtlSavedState>() {
113             @Override
114             public RtlSavedState createFromParcel(Parcel source,
115                     ClassLoader loader) {
116                 return new RtlSavedState(source, loader);
117             }
118 
119             @Override
120             public RtlSavedState createFromParcel(Parcel in) {
121                 return new RtlSavedState(in, null);
122             }
123 
124             @Override
125             public RtlSavedState[] newArray(int size) {
126                 return new RtlSavedState[size];
127             }
128         };
129 
130     }
131 
132 }
133