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 FragmentStatePagerAdapter2(FragmentManager fm)47 public FragmentStatePagerAdapter2(FragmentManager fm) { 48 mFragmentManager = fm; 49 } 50 51 /** 52 * Return the Fragment associated with a specified position. 53 */ getItem(int position)54 public abstract Fragment getItem(int position); 55 56 @Override startUpdate(ViewGroup container)57 public void startUpdate(ViewGroup container) { 58 } 59 60 @Override instantiateItem(ViewGroup container, int position)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 destroyItem(ViewGroup container, int position, Object object)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 setPrimaryItem(ViewGroup container, int position, Object object)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 finishUpdate(ViewGroup container)112 public void finishUpdate(ViewGroup container) { 113 if (mCurTransaction != null) { 114 mCurTransaction.commitAllowingStateLoss(); 115 mCurTransaction = null; 116 mFragmentManager.executePendingTransactions(); 117 } 118 } 119 120 @Override isViewFromObject(View view, Object object)121 public boolean isViewFromObject(View view, Object object) { 122 return ((Fragment) object).getView() == view; 123 } 124 setItemVisible(Fragment item, boolean visible)125 public void setItemVisible(Fragment item, boolean visible) { 126 FragmentCompat.setMenuVisibility(item, visible); 127 FragmentCompat.setUserVisibleHint(item, visible); 128 } 129 130 @Override notifyDataSetChanged()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 getFragmentAt(int position)150 public Fragment getFragmentAt(int position) { 151 return mFragments.valueAt(position); 152 } 153 154 } 155