ViewsStateBundle.java revision 81a36a4dd93bf2f14c2eb88ae01464f85ddb0706
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14package android.support.v17.leanback.widget; 15 16import android.os.Bundle; 17import android.os.Parcelable; 18import android.util.SparseArray; 19import android.view.View; 20 21/** 22 * Maintains a bundle of states for a group of views. Each view must have a unique id to identify 23 * it. There are four different strategies {@link #SAVE_NO_CHILD} {@link #SAVE_ON_SCREEN_CHILD} 24 * {@link #SAVE_LIMITED_CHILD} {@link #SAVE_ALL_CHILD}. 25 * <p> 26 * This class serves purpose of nested "listview" e.g. a vertical list of horizontal list. 27 * Vertical list maintains id->bundle mapping of all it's children (even the children is offscreen 28 * and being pruned). 29 * <p> 30 * The class is currently used within {@link GridLayoutManager}, but it might be used by other 31 * ViewGroup. 32 */ 33class ViewsStateBundle { 34 35 /** dont save states of any child views */ 36 public static final int SAVE_NO_CHILD = 0; 37 /** only save on screen child views, the states are lost when they become off screen */ 38 public static final int SAVE_ON_SCREEN_CHILD = 1; 39 /** save on screen views plus save off screen child views states up to {@link #getLimitNumber()} */ 40 public static final int SAVE_LIMITED_CHILD = 2; 41 /** 42 * save on screen views plus save off screen child views without any limitation. This might cause out 43 * of memory, only use it when you are dealing with limited data 44 */ 45 public static final int SAVE_ALL_CHILD = 3; 46 47 public static final int DEFAULT_LIMIT = 100; 48 49 private int mSavePolicy; 50 private int mLimitNumber; 51 52 private final Bundle mChildStates; 53 54 public ViewsStateBundle(int policy, int limit) { 55 mSavePolicy = policy; 56 mLimitNumber = limit; 57 mChildStates = new Bundle(); 58 } 59 60 public void clear() { 61 mChildStates.clear(); 62 } 63 64 public void remove(int id) { 65 if (!mChildStates.isEmpty()) { 66 mChildStates.remove(getSaveStatesKey(id)); 67 } 68 } 69 70 /** 71 * @return the saved views states 72 */ 73 public final Bundle getChildStates() { 74 return mChildStates; 75 } 76 77 /** 78 * @return the savePolicy, see {@link #SAVE_NO_CHILD} {@link #SAVE_ON_SCREEN_CHILD} 79 * {@link #SAVE_LIMITED_CHILD} {@link #SAVE_ALL_CHILD} 80 */ 81 public final int getSavePolicy() { 82 return mSavePolicy; 83 } 84 85 /** 86 * @return the limitNumber, only works when {@link #getSavePolicy()} is 87 * {@link #SAVE_LIMITED_CHILD} 88 */ 89 public final int getLimitNumber() { 90 return mLimitNumber; 91 } 92 93 /** 94 * @see ViewsStateBundle#getSavePolicy() 95 */ 96 public final void setSavePolicy(int savePolicy) { 97 this.mSavePolicy = savePolicy; 98 } 99 100 /** 101 * @see ViewsStateBundle#getLimitNumber() 102 */ 103 public final void setLimitNumber(int limitNumber) { 104 this.mLimitNumber = limitNumber; 105 } 106 107 /** 108 * Load view from states, it's none operation if the there is no state associated with the id. 109 * 110 * @param view view where loads into 111 * @param id unique id for the view within this ViewsStateBundle 112 */ 113 public final void loadView(View view, int id) { 114 String key = getSaveStatesKey(id); 115 SparseArray<Parcelable> container = mChildStates.getSparseParcelableArray(key); 116 if (container != null) { 117 view.restoreHierarchyState(container); 118 } 119 } 120 121 /** 122 * Save views regardless what's the current policy is. 123 * 124 * @param view view to save 125 * @param id unique id for the view within this ViewsStateBundle 126 */ 127 protected final void saveViewUnchecked(View view, int id) { 128 String key = getSaveStatesKey(id); 129 SparseArray<Parcelable> container = new SparseArray<Parcelable>(); 130 view.saveHierarchyState(container); 131 mChildStates.putSparseParcelableArray(key, container); 132 } 133 134 /** 135 * The on screen view is saved when policy is not {@link #SAVE_NO_CHILD}. 136 * 137 * @param view 138 * @param id 139 */ 140 public final void saveOnScreenView(View view, int id) { 141 if (mSavePolicy != SAVE_NO_CHILD) { 142 saveViewUnchecked(view, id); 143 } 144 } 145 146 /** 147 * Save off screen views according to policy. 148 * 149 * @param view view to save 150 * @param id unique id for the view within this ViewsStateBundle 151 */ 152 public final void saveOffscreenView(View view, int id) { 153 switch (mSavePolicy) { 154 case SAVE_LIMITED_CHILD: 155 if (mChildStates.size() > mLimitNumber) { 156 // TODO prune the Bundle to be under limit 157 } 158 // slip through next case section to save view 159 case SAVE_ALL_CHILD: 160 saveViewUnchecked(view, id); 161 break; 162 default: 163 break; 164 } 165 } 166 167 static String getSaveStatesKey(int id) { 168 return Integer.toString(id); 169 } 170} 171