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 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.widget.ExpandableListAdapter; 27 import android.widget.HeterogeneousExpandableList; 28 29 import java.util.ArrayList; 30 import java.util.List; 31 32 public 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 public int getGroupCount() { 103 return mItems.size(); 104 } 105 106 public int getChildrenCount(int groupPosition) { 107 AdapterItem item = mItems.get(groupPosition); 108 return item.getChildren().size(); 109 } 110 111 public Object getGroup(int groupPosition) { 112 return mItems.get(groupPosition); 113 } 114 115 public Object getChild(int groupPosition, int childPosition) { 116 return getChildItem(groupPosition, childPosition); 117 } 118 119 public View getGroupView(int groupPosition, boolean isExpanded, View convertView, 120 ViewGroup parent) { 121 // we don't care about recycling here because we never scroll. 122 AdapterItem item = mItems.get(groupPosition); 123 return getView(item, null /*parentItem*/, convertView, parent); 124 } 125 126 public View getChildView(int groupPosition, int childPosition, boolean isLastChild, 127 View convertView, ViewGroup parent) { 128 // we don't care about recycling here because we never scroll. 129 AdapterItem parentItem = mItems.get(groupPosition); 130 AdapterItem item = getChildItem(groupPosition, childPosition); 131 return getView(item, parentItem, convertView, parent); 132 } 133 134 public long getGroupId(int groupPosition) { 135 return groupPosition; 136 } 137 138 public long getChildId(int groupPosition, int childPosition) { 139 return childPosition; 140 } 141 142 public long getCombinedGroupId(long groupId) { 143 return groupId << 16 | 0x0000FFFF; 144 } 145 146 public long getCombinedChildId(long groupId, long childId) { 147 return groupId << 16 | childId; 148 } 149 150 public boolean isChildSelectable(int groupPosition, int childPosition) { 151 return true; 152 } 153 154 public void onGroupCollapsed(int groupPosition) { 155 // pass 156 } 157 158 public void onGroupExpanded(int groupPosition) { 159 // pass 160 } 161 162 // ---- HeterogeneousExpandableList 163 164 public int getChildType(int groupPosition, int childPosition) { 165 return getChildItem(groupPosition, childPosition).getType(); 166 } 167 168 public int getChildTypeCount() { 169 return mChildrenTypes.size(); 170 } 171 172 public int getGroupType(int groupPosition) { 173 return mItems.get(groupPosition).getType(); 174 } 175 176 public int getGroupTypeCount() { 177 return mGroupTypes.size(); 178 } 179 } 180