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