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