1/* 2 * Copyright (C) 2013 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.documentsui; 18 19import android.view.View; 20import android.view.ViewGroup; 21import android.widget.AdapterView; 22import android.widget.BaseAdapter; 23import android.widget.ListAdapter; 24 25import com.google.android.collect.Lists; 26 27import java.util.ArrayList; 28 29/** 30 * Adapter that combines multiple adapters as sections, asking each section to 31 * provide a header, and correctly handling item types across child adapters. 32 */ 33public class SectionedListAdapter extends BaseAdapter { 34 private ArrayList<SectionAdapter> mSections = Lists.newArrayList(); 35 36 public interface SectionAdapter extends ListAdapter { 37 public View getHeaderView(View convertView, ViewGroup parent); 38 } 39 40 public void clearSections() { 41 mSections.clear(); 42 notifyDataSetChanged(); 43 } 44 45 /** 46 * After mutating sections, you <em>must</em> 47 * {@link AdapterView#setAdapter(android.widget.Adapter)} to correctly 48 * recount view types. 49 */ 50 public void addSection(SectionAdapter adapter) { 51 mSections.add(adapter); 52 notifyDataSetChanged(); 53 } 54 55 @Override 56 public int getCount() { 57 int count = 0; 58 final int size = mSections.size(); 59 for (int i = 0; i < size; i++) { 60 count += mSections.get(i).getCount() + 1; 61 } 62 return count; 63 } 64 65 @Override 66 public Object getItem(int position) { 67 final int size = mSections.size(); 68 for (int i = 0; i < size; i++) { 69 final SectionAdapter section = mSections.get(i); 70 final int sectionSize = section.getCount() + 1; 71 72 // Check if position inside this section 73 if (position == 0) { 74 return section; 75 } else if (position < sectionSize) { 76 return section.getItem(position - 1); 77 } 78 79 // Otherwise jump into next section 80 position -= sectionSize; 81 } 82 throw new IllegalStateException("Unknown position " + position); 83 } 84 85 @Override 86 public long getItemId(int position) { 87 return position; 88 } 89 90 @Override 91 public View getView(int position, View convertView, ViewGroup parent) { 92 final int size = mSections.size(); 93 for (int i = 0; i < size; i++) { 94 final SectionAdapter section = mSections.get(i); 95 final int sectionSize = section.getCount() + 1; 96 97 // Check if position inside this section 98 if (position == 0) { 99 return section.getHeaderView(convertView, parent); 100 } else if (position < sectionSize) { 101 return section.getView(position - 1, convertView, parent); 102 } 103 104 // Otherwise jump into next section 105 position -= sectionSize; 106 } 107 throw new IllegalStateException("Unknown position " + position); 108 } 109 110 @Override 111 public boolean areAllItemsEnabled() { 112 return false; 113 } 114 115 @Override 116 public boolean isEnabled(int position) { 117 final int size = mSections.size(); 118 for (int i = 0; i < size; i++) { 119 final SectionAdapter section = mSections.get(i); 120 final int sectionSize = section.getCount() + 1; 121 122 // Check if position inside this section 123 if (position == 0) { 124 return false; 125 } else if (position < sectionSize) { 126 return section.isEnabled(position - 1); 127 } 128 129 // Otherwise jump into next section 130 position -= sectionSize; 131 } 132 throw new IllegalStateException("Unknown position " + position); 133 } 134 135 @Override 136 public int getItemViewType(int position) { 137 int type = 1; 138 final int size = mSections.size(); 139 for (int i = 0; i < size; i++) { 140 final SectionAdapter section = mSections.get(i); 141 final int sectionSize = section.getCount() + 1; 142 143 // Check if position inside this section 144 if (position == 0) { 145 return 0; 146 } else if (position < sectionSize) { 147 return type + section.getItemViewType(position - 1); 148 } 149 150 // Otherwise jump into next section 151 position -= sectionSize; 152 type += section.getViewTypeCount(); 153 } 154 throw new IllegalStateException("Unknown position " + position); 155 } 156 157 @Override 158 public int getViewTypeCount() { 159 int count = 1; 160 final int size = mSections.size(); 161 for (int i = 0; i < size; i++) { 162 count += mSections.get(i).getViewTypeCount(); 163 } 164 return count; 165 } 166} 167