Home | History | Annotate | Download | only in ui
      1 package com.android.packageinstaller.permission.ui;
      2 
      3 import android.annotation.Nullable;
      4 import android.os.Bundle;
      5 import android.support.v14.preference.PreferenceFragment;
      6 import android.support.v17.leanback.widget.VerticalGridView;
      7 import android.support.v7.preference.PreferenceScreen;
      8 import android.support.v7.widget.RecyclerView;
      9 import android.support.v7.widget.RecyclerView.AdapterDataObserver;
     10 import android.view.LayoutInflater;
     11 import android.view.View;
     12 import android.view.ViewGroup;
     13 import android.view.animation.Animation;
     14 import android.view.animation.Animation.AnimationListener;
     15 import android.view.animation.AnimationUtils;
     16 import android.widget.TextView;
     17 
     18 import com.android.packageinstaller.R;
     19 import com.android.packageinstaller.permission.utils.Utils;
     20 
     21 public abstract class PermissionsFrameFragment extends PreferenceFragment {
     22 
     23     private static final float WINDOW_ALIGNMENT_OFFSET_PERCENT = 50;
     24 
     25     private ViewGroup mPreferencesContainer;
     26 
     27     // TV-specific instance variables
     28     @Nullable private VerticalGridView mGridView;
     29 
     30     private View mLoadingView;
     31     private ViewGroup mPrefsView;
     32     private boolean mIsLoading;
     33 
     34     /**
     35      * Returns the view group that holds the preferences objects. This will
     36      * only be set after {@link #onCreateView} has been called.
     37      */
     38     protected final ViewGroup getPreferencesContainer() {
     39         return mPreferencesContainer;
     40     }
     41 
     42     @Override
     43     public View onCreateView(LayoutInflater inflater, ViewGroup container,
     44             Bundle savedInstanceState) {
     45         ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.permissions_frame, container,
     46                         false);
     47         mPrefsView = (ViewGroup) rootView.findViewById(R.id.prefs_container);
     48         if (mPrefsView == null) {
     49             mPrefsView = rootView;
     50         }
     51         mLoadingView = rootView.findViewById(R.id.loading_container);
     52         mPreferencesContainer = (ViewGroup) super.onCreateView(
     53                 inflater, mPrefsView, savedInstanceState);
     54         setLoading(mIsLoading, false, true /* force */);
     55         mPrefsView.addView(mPreferencesContainer);
     56         return rootView;
     57     }
     58 
     59     @Override
     60     public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
     61         PreferenceScreen preferences = getPreferenceScreen();
     62         if (preferences == null) {
     63             preferences = getPreferenceManager().createPreferenceScreen(getActivity());
     64             setPreferenceScreen(preferences);
     65         }
     66     }
     67 
     68     protected void setLoading(boolean loading, boolean animate) {
     69         setLoading(loading, animate, false);
     70     }
     71 
     72     private void setLoading(boolean loading, boolean animate, boolean force) {
     73         if (mIsLoading != loading || force) {
     74             mIsLoading = loading;
     75             if (getView() == null) {
     76                 // If there is no created view, there is no reason to animate.
     77                 animate = false;
     78             }
     79             if (mPrefsView != null) {
     80                 setViewShown(mPrefsView, !loading, animate);
     81             }
     82             if (mLoadingView != null) {
     83                 setViewShown(mLoadingView, loading, animate);
     84             }
     85         }
     86     }
     87 
     88     private void setViewShown(final View view, boolean shown, boolean animate) {
     89         if (animate) {
     90             Animation animation = AnimationUtils.loadAnimation(getContext(),
     91                     shown ? android.R.anim.fade_in : android.R.anim.fade_out);
     92             if (shown) {
     93                 view.setVisibility(View.VISIBLE);
     94             } else {
     95                 animation.setAnimationListener(new AnimationListener() {
     96                     @Override
     97                     public void onAnimationStart(Animation animation) {
     98                     }
     99 
    100                     @Override
    101                     public void onAnimationRepeat(Animation animation) {
    102                     }
    103 
    104                     @Override
    105                     public void onAnimationEnd(Animation animation) {
    106                         view.setVisibility(View.INVISIBLE);
    107                     }
    108                 });
    109             }
    110             view.startAnimation(animation);
    111         } else {
    112             view.clearAnimation();
    113             view.setVisibility(shown ? View.VISIBLE : View.INVISIBLE);
    114         }
    115     }
    116 
    117     @Override
    118     public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
    119             Bundle savedInstanceState) {
    120         if (Utils.isTelevision(getContext())) {
    121             mGridView = (VerticalGridView) inflater.inflate(
    122                     R.layout.leanback_preferences_list, parent, false);
    123             mGridView.setWindowAlignmentOffset(0);
    124             mGridView.setWindowAlignmentOffsetPercent(WINDOW_ALIGNMENT_OFFSET_PERCENT);
    125             mGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE);
    126             mGridView.setFocusScrollStrategy(VerticalGridView.FOCUS_SCROLL_ALIGNED);
    127             return mGridView;
    128         } else {
    129             return super.onCreateRecyclerView(inflater, parent, savedInstanceState);
    130         }
    131     }
    132 
    133     @Override
    134     protected RecyclerView.Adapter<?> onCreateAdapter(PreferenceScreen preferenceScreen) {
    135         final RecyclerView.Adapter<?> adapter = super.onCreateAdapter(preferenceScreen);
    136 
    137         if (adapter != null) {
    138             final TextView emptyView = (TextView) getView().findViewById(R.id.no_permissions);
    139             onSetEmptyText(emptyView);
    140             final RecyclerView recyclerView = getListView();
    141             adapter.registerAdapterDataObserver(new AdapterDataObserver() {
    142                 @Override
    143                 public void onChanged() {
    144                     checkEmpty();
    145                 }
    146 
    147                 @Override
    148                 public void onItemRangeInserted(int positionStart, int itemCount) {
    149                     checkEmpty();
    150                 }
    151 
    152                 @Override
    153                 public void onItemRangeRemoved(int positionStart, int itemCount) {
    154                     checkEmpty();
    155                 }
    156 
    157                 private void checkEmpty() {
    158                     boolean isEmpty = adapter.getItemCount() == 0;
    159                     emptyView.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
    160                     recyclerView.setVisibility(isEmpty ? View.GONE : View.VISIBLE);
    161                     if (!isEmpty && mGridView != null) {
    162                         mGridView.requestFocus();
    163                     }
    164                 }
    165             });
    166 
    167             boolean isEmpty = adapter.getItemCount() == 0;
    168             emptyView.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
    169             recyclerView.setVisibility(isEmpty ? View.GONE : View.VISIBLE);
    170             if (!isEmpty && mGridView != null) {
    171                 mGridView.requestFocus();
    172             }
    173         }
    174 
    175         return adapter;
    176     }
    177 
    178     /**
    179      * Hook for subclasses to change the default text of the empty view.
    180      * Base implementation leaves the default empty view text.
    181      *
    182      * @param textView the empty text view
    183      */
    184     protected void onSetEmptyText(TextView textView) {
    185     }
    186 }
    187 
    188