/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.documentsui; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ListAdapter; import com.google.android.collect.Lists; import java.util.ArrayList; /** * Adapter that combines multiple adapters as sections, asking each section to * provide a header, and correctly handling item types across child adapters. */ public class SectionedListAdapter extends BaseAdapter { private ArrayList mSections = Lists.newArrayList(); public interface SectionAdapter extends ListAdapter { public View getHeaderView(View convertView, ViewGroup parent); } public void clearSections() { mSections.clear(); notifyDataSetChanged(); } /** * After mutating sections, you must * {@link AdapterView#setAdapter(android.widget.Adapter)} to correctly * recount view types. */ public void addSection(SectionAdapter adapter) { mSections.add(adapter); notifyDataSetChanged(); } @Override public int getCount() { int count = 0; final int size = mSections.size(); for (int i = 0; i < size; i++) { count += mSections.get(i).getCount() + 1; } return count; } @Override public Object getItem(int position) { final int size = mSections.size(); for (int i = 0; i < size; i++) { final SectionAdapter section = mSections.get(i); final int sectionSize = section.getCount() + 1; // Check if position inside this section if (position == 0) { return section; } else if (position < sectionSize) { return section.getItem(position - 1); } // Otherwise jump into next section position -= sectionSize; } throw new IllegalStateException("Unknown position " + position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { final int size = mSections.size(); for (int i = 0; i < size; i++) { final SectionAdapter section = mSections.get(i); final int sectionSize = section.getCount() + 1; // Check if position inside this section if (position == 0) { return section.getHeaderView(convertView, parent); } else if (position < sectionSize) { return section.getView(position - 1, convertView, parent); } // Otherwise jump into next section position -= sectionSize; } throw new IllegalStateException("Unknown position " + position); } @Override public boolean areAllItemsEnabled() { return false; } @Override public boolean isEnabled(int position) { final int size = mSections.size(); for (int i = 0; i < size; i++) { final SectionAdapter section = mSections.get(i); final int sectionSize = section.getCount() + 1; // Check if position inside this section if (position == 0) { return false; } else if (position < sectionSize) { return section.isEnabled(position - 1); } // Otherwise jump into next section position -= sectionSize; } throw new IllegalStateException("Unknown position " + position); } @Override public int getItemViewType(int position) { int type = 1; final int size = mSections.size(); for (int i = 0; i < size; i++) { final SectionAdapter section = mSections.get(i); final int sectionSize = section.getCount() + 1; // Check if position inside this section if (position == 0) { return 0; } else if (position < sectionSize) { return type + section.getItemViewType(position - 1); } // Otherwise jump into next section position -= sectionSize; type += section.getViewTypeCount(); } throw new IllegalStateException("Unknown position " + position); } @Override public int getViewTypeCount() { int count = 1; final int size = mSections.size(); for (int i = 0; i < size; i++) { count += mSections.get(i).getViewTypeCount(); } return count; } }