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 41 public RtlCompatibleViewPager(Context context) { 42 this(context, null /* attrs */); 43 } 44 45 public RtlCompatibleViewPager(Context context, AttributeSet attrs) { 46 super(context, attrs); 47 } 48 49 @Override 50 public int getCurrentItem() { 51 return getRtlAwareIndex(super.getCurrentItem()); 52 } 53 54 @Override 55 public void setCurrentItem(int item) { 56 super.setCurrentItem(getRtlAwareIndex(item)); 57 } 58 59 @Override 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 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 */ 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 96 public RtlSavedState(Parcelable superState) { 97 super(superState); 98 } 99 100 private RtlSavedState(Parcel in, ClassLoader loader) { 101 super(in, loader); 102 position = in.readInt(); 103 } 104 105 @Override 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