1 /* 2 * Copyright (C) 2011 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.layoutlib.bridge.impl.binding; 18 19 import com.android.ide.common.rendering.api.AdapterBinding; 20 import com.android.ide.common.rendering.api.DataBindingItem; 21 import com.android.ide.common.rendering.api.IProjectCallback; 22 import com.android.ide.common.rendering.api.ResourceReference; 23 import com.android.util.Pair; 24 25 import android.database.DataSetObserver; 26 import android.view.View; 27 import android.view.ViewGroup; 28 import android.widget.ExpandableListAdapter; 29 import android.widget.HeterogeneousExpandableList; 30 31 import java.util.ArrayList; 32 import java.util.List; 33 34 @SuppressWarnings("deprecation") 35 public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList { 36 37 private final IProjectCallback mCallback; 38 private final ResourceReference mAdapterRef; 39 private boolean mSkipCallbackParser = false; 40 41 protected final List<AdapterItem> mItems = new ArrayList<AdapterItem>(); 42 43 // don't use a set because the order is important. 44 private final List<ResourceReference> mGroupTypes = new ArrayList<ResourceReference>(); 45 private final List<ResourceReference> mChildrenTypes = new ArrayList<ResourceReference>(); 46 47 public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding, 48 IProjectCallback callback) { 49 mAdapterRef = adapterRef; 50 mCallback = callback; 51 52 createItems(binding, binding.getItemCount(), binding.getRepeatCount(), mGroupTypes, 1); 53 } 54 55 private void createItems(Iterable<DataBindingItem> iterable, final int itemCount, 56 final int repeatCount, List<ResourceReference> types, int depth) { 57 // Need an array to count for each type. 58 // This is likely too big, but is the max it can be. 59 int[] typeCount = new int[itemCount]; 60 61 // we put several repeating sets. 62 for (int r = 0 ; r < repeatCount ; r++) { 63 // loop on the type of list items, and add however many for each type. 64 for (DataBindingItem dataBindingItem : iterable) { 65 ResourceReference viewRef = dataBindingItem.getViewReference(); 66 int typeIndex = types.indexOf(viewRef); 67 if (typeIndex == -1) { 68 typeIndex = types.size(); 69 types.add(viewRef); 70 } 71 72 List<DataBindingItem> children = dataBindingItem.getChildren(); 73 int count = dataBindingItem.getCount(); 74 75 // if there are children, we use the count as a repeat count for the children. 76 if (children.size() > 0) { 77 count = 1; 78 } 79 80 int index = typeCount[typeIndex]; 81 typeCount[typeIndex] += count; 82 83 for (int k = 0 ; k < count ; k++) { 84 AdapterItem item = new AdapterItem(dataBindingItem, typeIndex, mItems.size(), 85 index++); 86 mItems.add(item); 87 88 if (children.size() > 0) { 89 createItems(dataBindingItem, depth + 1); 90 } 91 } 92 } 93 } 94 } 95 96 private void createItems(DataBindingItem item, int depth) { 97 if (depth == 2) { 98 createItems(item, item.getChildren().size(), item.getCount(), mChildrenTypes, depth); 99 } 100 } 101 102 private AdapterItem getChildItem(int groupPosition, int childPosition) { 103 AdapterItem item = mItems.get(groupPosition); 104 105 List<AdapterItem> children = item.getChildren(); 106 return children.get(childPosition); 107 } 108 109 // ---- ExpandableListAdapter 110 111 @Override 112 public int getGroupCount() { 113 return mItems.size(); 114 } 115 116 @Override 117 public int getChildrenCount(int groupPosition) { 118 AdapterItem item = mItems.get(groupPosition); 119 return item.getChildren().size(); 120 } 121 122 @Override 123 public Object getGroup(int groupPosition) { 124 return mItems.get(groupPosition); 125 } 126 127 @Override 128 public Object getChild(int groupPosition, int childPosition) { 129 return getChildItem(groupPosition, childPosition); 130 } 131 132 @Override 133 public View getGroupView(int groupPosition, boolean isExpanded, View convertView, 134 ViewGroup parent) { 135 // we don't care about recycling here because we never scroll. 136 AdapterItem item = mItems.get(groupPosition); 137 Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentItem*/, parent, 138 mCallback, mAdapterRef, mSkipCallbackParser); 139 mSkipCallbackParser = pair.getSecond(); 140 return pair.getFirst(); 141 } 142 143 @Override 144 public View getChildView(int groupPosition, int childPosition, boolean isLastChild, 145 View convertView, ViewGroup parent) { 146 // we don't care about recycling here because we never scroll. 147 AdapterItem parentItem = mItems.get(groupPosition); 148 AdapterItem item = getChildItem(groupPosition, childPosition); 149 Pair<View, Boolean> pair = AdapterHelper.getView(item, parentItem, parent, mCallback, 150 mAdapterRef, mSkipCallbackParser); 151 mSkipCallbackParser = pair.getSecond(); 152 return pair.getFirst(); 153 } 154 155 @Override 156 public long getGroupId(int groupPosition) { 157 return groupPosition; 158 } 159 160 @Override 161 public long getChildId(int groupPosition, int childPosition) { 162 return childPosition; 163 } 164 165 @Override 166 public long getCombinedGroupId(long groupId) { 167 return groupId << 16 | 0x0000FFFF; 168 } 169 170 @Override 171 public long getCombinedChildId(long groupId, long childId) { 172 return groupId << 16 | childId; 173 } 174 175 @Override 176 public boolean isChildSelectable(int groupPosition, int childPosition) { 177 return true; 178 } 179 180 @Override 181 public void onGroupCollapsed(int groupPosition) { 182 // pass 183 } 184 185 @Override 186 public void onGroupExpanded(int groupPosition) { 187 // pass 188 } 189 190 @Override 191 public void registerDataSetObserver(DataSetObserver observer) { 192 // pass 193 } 194 195 @Override 196 public void unregisterDataSetObserver(DataSetObserver observer) { 197 // pass 198 } 199 200 @Override 201 public boolean hasStableIds() { 202 return true; 203 } 204 205 @Override 206 public boolean areAllItemsEnabled() { 207 return true; 208 } 209 210 @Override 211 public boolean isEmpty() { 212 return mItems.isEmpty(); 213 } 214 215 // ---- HeterogeneousExpandableList 216 217 @Override 218 public int getChildType(int groupPosition, int childPosition) { 219 return getChildItem(groupPosition, childPosition).getType(); 220 } 221 222 @Override 223 public int getChildTypeCount() { 224 return mChildrenTypes.size(); 225 } 226 227 @Override 228 public int getGroupType(int groupPosition) { 229 return mItems.get(groupPosition).getType(); 230 } 231 232 @Override 233 public int getGroupTypeCount() { 234 return mGroupTypes.size(); 235 } 236 } 237