Home | History | Annotate | Download | only in old
      1 /*
      2  * Copyright (C) 2014 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.tv.settings.dialog.old;
     18 
     19 import android.animation.Animator;
     20 import android.os.Bundle;
     21 import android.view.LayoutInflater;
     22 import android.view.View;
     23 import android.view.ViewGroup;
     24 import android.view.ViewGroup.LayoutParams;
     25 import android.view.ViewPropertyAnimator;
     26 import android.view.animation.DecelerateInterpolator;
     27 
     28 import com.android.tv.settings.R;
     29 import com.android.tv.settings.widget.ScrollAdapter;
     30 import com.android.tv.settings.widget.ScrollAdapterView;
     31 import com.android.tv.settings.widget.ScrollAdapterView.OnScrollListener;
     32 
     33 /**
     34  * Fragment which uses a ScrollAdapterView as its basic UI.
     35  * <p>
     36  * This fragment is meant to be inserted as the action fragment into a {@link DialogActivity}.
     37  * <p>
     38  * Users can either subclass this or just use listener objects to receive life cycle events.
     39  */
     40 public class BaseScrollAdapterFragment implements OnScrollListener {
     41     private static final String STATE_SELECTION = "BaseScrollAdapterFragment.selection";
     42     private int mAnimationDuration;
     43     private final LiteFragment mFragment;
     44 
     45     private ScrollAdapter mAdapter;
     46     private ScrollAdapterView mScrollAdapterView;
     47     private View mSelectorView;
     48     private View mSelectedView = null;
     49     private volatile boolean mFadedOut = true;
     50 
     51     public BaseScrollAdapterFragment(LiteFragment fragment) {
     52         mFragment = fragment;
     53     }
     54 
     55     public View onCreateView(LayoutInflater inflater, ViewGroup container,
     56             Bundle savedInstanceState) {
     57         View v = inflater.inflate(R.layout.settings_list, container, false);
     58         mScrollAdapterView = null;
     59         return v;
     60     }
     61 
     62     public void onSaveInstanceState(Bundle outState) {
     63         if (mScrollAdapterView != null) {
     64             outState.putInt(STATE_SELECTION, getSelectedItemPosition());
     65         }
     66     }
     67 
     68     public void onViewCreated(View view, Bundle savedInstanceState) {
     69         ensureList();
     70         if (savedInstanceState != null) {
     71             setSelection(savedInstanceState.getInt(STATE_SELECTION, 0));
     72         }
     73     }
     74 
     75     public boolean hasCreatedView() {
     76         return mFragment != null && mFragment.getView() != null;
     77     }
     78 
     79     public ScrollAdapterView getScrollAdapterView() {
     80         ensureList();
     81         return mScrollAdapterView;
     82     }
     83 
     84     public ScrollAdapter getAdapter() {
     85         return mAdapter;
     86     }
     87 
     88     public void setAdapter(ScrollAdapter adapter) {
     89         mAdapter = adapter;
     90         if (mScrollAdapterView != null) {
     91             mScrollAdapterView.setAdapter(mAdapter);
     92         }
     93     }
     94 
     95     public void setSelection(int position) {
     96         mScrollAdapterView.setSelection(position);
     97     }
     98 
     99     public void setSelectionSmooth(int position) {
    100         mScrollAdapterView.setSelectionSmooth(position);
    101     }
    102 
    103     public int getSelectedItemPosition() {
    104         return mScrollAdapterView.getSelectedItemPosition();
    105     }
    106 
    107     public void ensureList() {
    108         if (mScrollAdapterView != null) {
    109             return;
    110         }
    111         View root = mFragment.getView();
    112         if (root == null) {
    113             throw new IllegalStateException("Content view not created yet.");
    114         }
    115         if (root instanceof ScrollAdapterView) {
    116             mScrollAdapterView = (ScrollAdapterView) root;
    117             mSelectorView = null;
    118         } else {
    119             mScrollAdapterView = (ScrollAdapterView) root.findViewById(R.id.list);
    120             if (mScrollAdapterView == null) {
    121                 throw new IllegalStateException("No scroll adapter view exists.");
    122             }
    123             mSelectorView = root.findViewById(R.id.selector);
    124         }
    125         if (mScrollAdapterView != null) {
    126             mScrollAdapterView.requestFocusFromTouch();
    127             if (mAdapter != null) {
    128                 mScrollAdapterView.setAdapter(mAdapter);
    129             }
    130             if (mSelectorView != null) {
    131                 mAnimationDuration = mFragment.getActivity()
    132                         .getResources().getInteger(R.integer.dialog_animation_duration);
    133                 mScrollAdapterView.addOnScrollListener(this);
    134             }
    135         }
    136     }
    137 
    138     /**
    139      * Sets {@link BaseScrollAdapterFragment#mFadedOut}
    140      *
    141      * {@link BaseScrollAdapterFragment#mFadedOut} is true, iff
    142      * {@link BaseScrollAdapterFragment#mSelectorView} has an alpha of 0
    143      * (faded out). If false the view either has an alpha of 1 (visible) or
    144      * is in the process of animating.
    145      */
    146     private class Listener implements Animator.AnimatorListener {
    147         private final boolean mFadingOut;
    148         private boolean mCanceled;
    149 
    150         public Listener(boolean fadingOut) {
    151             mFadingOut = fadingOut;
    152         }
    153 
    154         @Override
    155         public void onAnimationStart(Animator animation) {
    156             if(!mFadingOut) {
    157                 mFadedOut = false;
    158             }
    159         }
    160 
    161         @Override
    162         public void onAnimationEnd(Animator animation) {
    163             if (!mCanceled && mFadingOut) {
    164                 mFadedOut = true;
    165             }
    166         }
    167 
    168         @Override
    169         public void onAnimationCancel(Animator animation) {
    170             mCanceled = true;
    171         }
    172 
    173         @Override
    174         public void onAnimationRepeat(Animator animation) {
    175         }
    176     }
    177 
    178     // We want to fade in the selector if we've stopped scrolling on it (mainPosition = 0).
    179     // If mainPosition is not 0, we want to ensure to dim the selector if we haven't already.
    180     // we dim the last highlighted view so that while a user is scrolling, nothing is highlighted.
    181     @Override
    182     public synchronized void onScrolled(View view, int position, float mainPosition,
    183             float secondPosition) {
    184         boolean hasFocus = (mainPosition == 0.0);
    185         if (hasFocus) {
    186             if (view != null) {
    187                 // The selector starts with a height of 0. In order to scale up
    188                 // from
    189                 // 0 we first need the set the height to 1 and scale form there.
    190                 int selectorHeight = mSelectorView.getHeight();
    191                 if (selectorHeight == 0) {
    192                     LayoutParams lp = mSelectorView.getLayoutParams();
    193                     lp.height = selectorHeight = mFragment.getActivity().getResources()
    194                             .getDimensionPixelSize(R.dimen.action_fragment_selector_min_height);
    195                     mSelectorView.setLayoutParams(lp);
    196                 }
    197                 float scaleY = (float) view.getHeight() / selectorHeight;
    198                 ViewPropertyAnimator animation = mSelectorView.animate()
    199                         .alpha(1f)
    200                         .setListener(new Listener(false))
    201                         .setDuration(mAnimationDuration)
    202                         .setInterpolator(new DecelerateInterpolator(2f));
    203                 if (mFadedOut) {
    204                     // selector is completely faded out, so we can just scale
    205                     // before fading in.
    206                     mSelectorView.setScaleY(scaleY);
    207                 } else {
    208                     // selector is not faded out, so we must animate the scale
    209                     // as we fade in.
    210                     animation.scaleY(scaleY);
    211                 }
    212                 animation.start();
    213                 mSelectedView = view;
    214             } else {
    215                 LayoutParams lp = mSelectorView.getLayoutParams();
    216                 lp.height = 0;
    217                 mSelectorView.setLayoutParams(lp);
    218             }
    219         } else if (mSelectedView != null) {
    220             mSelectorView.animate()
    221                     .alpha(0f)
    222                     .setDuration(mAnimationDuration)
    223                     .setInterpolator(new DecelerateInterpolator(2f))
    224                     .setListener(new Listener(true))
    225                     .start();
    226             mSelectedView = null;
    227         }
    228     }
    229 }
    230