Home | History | Annotate | Download | only in timer
      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.deskclock.timer;
     18 
     19 import android.app.Fragment;
     20 import android.app.FragmentManager;
     21 import android.app.FragmentTransaction;
     22 import android.support.v13.app.FragmentCompat;
     23 import android.support.v13.app.FragmentStatePagerAdapter;
     24 import android.support.v4.util.SparseArrayCompat;
     25 import android.support.v4.view.PagerAdapter;
     26 import android.view.View;
     27 import android.view.ViewGroup;
     28 
     29 /**
     30  * Forked from support lib's {@link FragmentStatePagerAdapter}, with some minor
     31  * changes that couldn't be accomplished through subclassing: we need to override the
     32  * onDataSetChanged method using the private member mFragments which cannot be accessed outside.
     33  *
     34  * This class is used for TimerFragment's vertical view pager only. It removed the save/restore
     35  * functionality, because all the fragments needs to be destroyed whenever TimerFragment's
     36  * onPause, in order to bind the newly created timer view with the new pager fragment.
     37  */
     38 public abstract class FragmentStatePagerAdapter2 extends PagerAdapter {
     39 
     40     private final FragmentManager mFragmentManager;
     41     private FragmentTransaction mCurTransaction = null;
     42 
     43     private SparseArrayCompat<Fragment> mFragments = new SparseArrayCompat<Fragment>();
     44     private Fragment mCurrentPrimaryItem = null;
     45 
     46 
     47     public FragmentStatePagerAdapter2(FragmentManager fm) {
     48         mFragmentManager = fm;
     49     }
     50 
     51     /**
     52      * Return the Fragment associated with a specified position.
     53      */
     54     public abstract Fragment getItem(int position);
     55 
     56     @Override
     57     public void startUpdate(ViewGroup container) {
     58     }
     59 
     60     @Override
     61     public Object instantiateItem(ViewGroup container, int position) {
     62         // If we already have this item instantiated, there is nothing
     63         // to do.  This can happen when we are restoring the entire pager
     64         // from its saved state, where the fragment manager has already
     65         // taken care of restoring the fragments we previously had instantiated.
     66         final Fragment existing = mFragments.get(position);
     67         if (existing != null) {
     68             return existing;
     69         }
     70 
     71         if (mCurTransaction == null) {
     72             mCurTransaction = mFragmentManager.beginTransaction();
     73         }
     74 
     75         Fragment fragment = getItem(position);
     76         if (fragment != mCurrentPrimaryItem) {
     77             setItemVisible(fragment, false);
     78         }
     79         mFragments.put(position, fragment);
     80         mCurTransaction.add(container.getId(), fragment);
     81 
     82         return fragment;
     83     }
     84 
     85     @Override
     86     public void destroyItem(ViewGroup container, int position, Object object) {
     87         Fragment fragment = (Fragment) object;
     88 
     89         if (mCurTransaction == null) {
     90             mCurTransaction = mFragmentManager.beginTransaction();
     91         }
     92         mFragments.delete(position);
     93 
     94         mCurTransaction.remove(fragment);
     95     }
     96 
     97     @Override
     98     public void setPrimaryItem(ViewGroup container, int position, Object object) {
     99         Fragment fragment = (Fragment) object;
    100         if (fragment != mCurrentPrimaryItem) {
    101             if (mCurrentPrimaryItem != null) {
    102                 setItemVisible(mCurrentPrimaryItem, false);
    103             }
    104             if (fragment != null) {
    105                 setItemVisible(fragment, true);
    106             }
    107             mCurrentPrimaryItem = fragment;
    108         }
    109     }
    110 
    111     @Override
    112     public void finishUpdate(ViewGroup container) {
    113         if (mCurTransaction != null) {
    114             mCurTransaction.commitAllowingStateLoss();
    115             mCurTransaction = null;
    116             mFragmentManager.executePendingTransactions();
    117         }
    118     }
    119 
    120     @Override
    121     public boolean isViewFromObject(View view, Object object) {
    122         return ((Fragment) object).getView() == view;
    123     }
    124 
    125     public void setItemVisible(Fragment item, boolean visible) {
    126         FragmentCompat.setMenuVisibility(item, visible);
    127         FragmentCompat.setUserVisibleHint(item, visible);
    128     }
    129 
    130     @Override
    131     public void notifyDataSetChanged() {
    132         // update positions in mFragments
    133         SparseArrayCompat<Fragment> newFragments =
    134                 new SparseArrayCompat<Fragment>(mFragments.size());
    135         for (int i = 0; i < mFragments.size(); i++) {
    136             final int oldPos = mFragments.keyAt(i);
    137             final Fragment f = mFragments.valueAt(i);
    138             final int newPos = getItemPosition(f);
    139 
    140             if (newPos != POSITION_NONE) {
    141                 final int pos = (newPos >= 0) ? newPos : oldPos;
    142                 newFragments.put(pos, f);
    143             }
    144         }
    145         mFragments = newFragments;
    146 
    147         super.notifyDataSetChanged();
    148     }
    149 
    150     public Fragment getFragmentAt(int position) {
    151         return mFragments.valueAt(position);
    152     }
    153 
    154 }
    155