15bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam/* 25bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * Copyright (C) 2015 The Android Open Source Project 35bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * 45bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * Licensed under the Apache License, Version 2.0 (the "License"); 55bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * you may not use this file except in compliance with the License. 65bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * You may obtain a copy of the License at 75bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * 85bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * http://www.apache.org/licenses/LICENSE-2.0 95bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * 105bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * Unless required by applicable law or agreed to in writing, software 115bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * distributed under the License is distributed on an "AS IS" BASIS, 125bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * See the License for the specific language governing permissions and 145bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * limitations under the License. 155bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam */ 165bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 175bf291fde3dfd64f264d525534730514a279c8fcMaurice Lampackage com.android.setupwizardlib.items; 185bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 195bf291fde3dfd64f264d525534730514a279c8fcMaurice Lamimport android.util.SparseIntArray; 205bf291fde3dfd64f264d525534730514a279c8fcMaurice Lamimport android.view.LayoutInflater; 215bf291fde3dfd64f264d525534730514a279c8fcMaurice Lamimport android.view.View; 225bf291fde3dfd64f264d525534730514a279c8fcMaurice Lamimport android.view.ViewGroup; 235bf291fde3dfd64f264d525534730514a279c8fcMaurice Lamimport android.widget.BaseAdapter; 245bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 255bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam/** 26960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam * An adapter typically used with ListView to display an 27960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam * {@link com.android.setupwizardlib.items.ItemHierarchy}. The item hierarchy used to create this 28960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam * adapter can be inflated by {@link ItemInflater} from XML. 295bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam */ 30960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lampublic class ItemAdapter extends BaseAdapter implements ItemHierarchy.Observer { 315bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 32960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam private final ItemHierarchy mItemHierarchy; 335bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam private ViewTypes mViewTypes = new ViewTypes(); 345bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 35960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam public ItemAdapter(ItemHierarchy hierarchy) { 36960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam mItemHierarchy = hierarchy; 37960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam mItemHierarchy.registerObserver(this); 385bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam refreshViewTypes(); 395bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 405bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 415bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam @Override 425bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam public int getCount() { 43960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam return mItemHierarchy.getCount(); 445bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 455bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 465bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam @Override 47960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam public IItem getItem(int position) { 48960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam return mItemHierarchy.getItemAt(position); 495bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 505bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 515bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam @Override 525bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam public long getItemId(int position) { 535bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam return position; 545bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 555bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 565bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam @Override 575bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam public int getItemViewType(int position) { 58960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam IItem item = getItem(position); 59960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam int layoutRes = item.getLayoutResource(); 605bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam return mViewTypes.get(layoutRes); 615bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 625bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 635bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam @Override 645bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam public int getViewTypeCount() { 655bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam return mViewTypes.size(); 665bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 675bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 68960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam private void refreshViewTypes() { 69960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam for (int i = 0; i < getCount(); i++) { 70960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam IItem item = getItem(i); 715bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam mViewTypes.add(item.getLayoutResource()); 725bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 735bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 745bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 755bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam @Override 765bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam public View getView(int position, View convertView, ViewGroup parent) { 77960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam IItem item = getItem(position); 785bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam if (convertView == null) { 795bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 805bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam convertView = inflater.inflate(item.getLayoutResource(), parent, false); 815bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 825bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam item.onBindView(convertView); 835bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam return convertView; 845bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 855bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 86960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam @Override 87960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam public void onChanged(ItemHierarchy hierarchy) { 88960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam refreshViewTypes(); 89960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam notifyDataSetChanged(); 90960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam } 91960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam 92960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam @Override 93ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam public void onItemRangeChanged(ItemHierarchy itemHierarchy, int positionStart, int itemCount) { 94ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam onChanged(itemHierarchy); 95ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam } 96ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam 97ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam @Override 98ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam public void onItemRangeInserted(ItemHierarchy itemHierarchy, int positionStart, int itemCount) { 99ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam onChanged(itemHierarchy); 100ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam } 101ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam 102ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam @Override 103ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam public void onItemRangeMoved(ItemHierarchy itemHierarchy, int fromPosition, int toPosition, 104ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam int itemCount) { 105ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam onChanged(itemHierarchy); 106ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam } 107ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam 108ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam @Override 109ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam public void onItemRangeRemoved(ItemHierarchy itemHierarchy, int positionStart, int itemCount) { 110ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam onChanged(itemHierarchy); 111ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam } 112ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam 113ab45bdf67a01ba13efb45334cc43f9632de6f034Maurice Lam @Override 114960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam public boolean isEnabled(int position) { 115960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam return getItem(position).isEnabled(); 116960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam } 117960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam 118960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam public ItemHierarchy findItemById(int id) { 119960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam return mItemHierarchy.findItemById(id); 120960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam } 121960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam 122960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam public ItemHierarchy getRootItemHierarchy() { 123960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam return mItemHierarchy; 124960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam } 125960c0ea0b1d36904beef0f01715dd43a211e88caMaurice Lam 1265bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam /** 1275bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * A helper class to pack a sparse set of integers (e.g. resource IDs) to a contiguous list of 1285bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * integers (e.g. adapter positions), providing mapping to retrieve the original ID from a given 1295bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * position. This is used to pack the view types of the adapter into contiguous integers from 1305bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam * a given layout resource. 1315bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam */ 1325bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam private static class ViewTypes { 1335bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam private SparseIntArray mPositionMap = new SparseIntArray(); 1345bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam private int nextPosition = 0; 1355bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 1365bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam public int add(int id) { 1375bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam if (mPositionMap.indexOfKey(id) < 0) { 1385bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam mPositionMap.put(id, nextPosition); 1395bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam nextPosition++; 1405bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 1415bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam return mPositionMap.get(id); 1425bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 1435bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 1445bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam public int size() { 1455bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam return mPositionMap.size(); 1465bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 1475bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam 1485bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam public int get(int id) { 1495bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam return mPositionMap.get(id); 1505bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 1515bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam } 1525bf291fde3dfd64f264d525534730514a279c8fcMaurice Lam} 153