Home | History | Annotate | Download | only in widget
      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