166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey/*
266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Copyright (C) 2013 The Android Open Source Project
366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey *
466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * you may not use this file except in compliance with the License.
666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * You may obtain a copy of the License at
766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey *
866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey *
1066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Unless required by applicable law or agreed to in writing, software
1166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
1266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * See the License for the specific language governing permissions and
1466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * limitations under the License.
1566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey */
1666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
1766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeypackage com.android.documentsui;
1866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
1966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.View;
2066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.ViewGroup;
2154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.widget.AdapterView;
2266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.BaseAdapter;
2366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.ListAdapter;
2466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
2566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport java.util.ArrayList;
2666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
2766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey/**
2866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Adapter that combines multiple adapters as sections, asking each section to
2966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * provide a header, and correctly handling item types across child adapters.
3066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey */
3166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeypublic class SectionedListAdapter extends BaseAdapter {
3258efce36cd1b26006e08ddd696292bf06fc34c81Steve McKay    private ArrayList<SectionAdapter> mSections = new ArrayList<>();
3366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
3466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public interface SectionAdapter extends ListAdapter {
3566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        public View getHeaderView(View convertView, ViewGroup parent);
3666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
3766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
3866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public void clearSections() {
3966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        mSections.clear();
4066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        notifyDataSetChanged();
4166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
4266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
4354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey    /**
4454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey     * After mutating sections, you <em>must</em>
4554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey     * {@link AdapterView#setAdapter(android.widget.Adapter)} to correctly
4654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey     * recount view types.
4754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey     */
4866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public void addSection(SectionAdapter adapter) {
4966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        mSections.add(adapter);
5066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        notifyDataSetChanged();
5166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
5266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
5366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
5466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public int getCount() {
5566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        int count = 0;
5666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
5766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
5866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            count += mSections.get(i).getCount() + 1;
5966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
6066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        return count;
6166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
6266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
6366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
6466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public Object getItem(int position) {
6566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
6666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
6766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final SectionAdapter section = mSections.get(i);
6866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final int sectionSize = section.getCount() + 1;
6966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
7066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Check if position inside this section
7166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (position == 0) {
7266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return section;
7366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            } else if (position < sectionSize) {
7466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return section.getItem(position - 1);
7566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
7666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
7766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Otherwise jump into next section
7866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            position -= sectionSize;
7966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
8066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        throw new IllegalStateException("Unknown position " + position);
8166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
8266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
8366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
8466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public long getItemId(int position) {
8566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        return position;
8666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
8766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
8866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
8966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public View getView(int position, View convertView, ViewGroup parent) {
9066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
9166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
9266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final SectionAdapter section = mSections.get(i);
9366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final int sectionSize = section.getCount() + 1;
9466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
9566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Check if position inside this section
9666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (position == 0) {
9766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return section.getHeaderView(convertView, parent);
9866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            } else if (position < sectionSize) {
9966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return section.getView(position - 1, convertView, parent);
10066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
10166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
10266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Otherwise jump into next section
10366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            position -= sectionSize;
10466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
10566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        throw new IllegalStateException("Unknown position " + position);
10666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
10766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
10866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
10966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public boolean areAllItemsEnabled() {
11066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        return false;
11166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
11266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
11366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
11466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public boolean isEnabled(int position) {
11566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
11666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
11766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final SectionAdapter section = mSections.get(i);
11866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final int sectionSize = section.getCount() + 1;
11966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
12066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Check if position inside this section
12166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (position == 0) {
12266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return false;
12366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            } else if (position < sectionSize) {
12454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                return section.isEnabled(position - 1);
12566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
12666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
12766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Otherwise jump into next section
12866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            position -= sectionSize;
12966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
13066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        throw new IllegalStateException("Unknown position " + position);
13166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
13266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
13366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
13466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public int getItemViewType(int position) {
13566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        int type = 1;
13666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
13766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
13866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final SectionAdapter section = mSections.get(i);
13966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final int sectionSize = section.getCount() + 1;
14066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
14166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Check if position inside this section
14266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (position == 0) {
14366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return 0;
14466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            } else if (position < sectionSize) {
14566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return type + section.getItemViewType(position - 1);
14666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
14766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
14866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Otherwise jump into next section
14966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            position -= sectionSize;
15066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            type += section.getViewTypeCount();
15166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
15266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        throw new IllegalStateException("Unknown position " + position);
15366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
15466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
15566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
15666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public int getViewTypeCount() {
15766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        int count = 1;
15866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
15966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
16066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            count += mSections.get(i).getViewTypeCount();
16166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
16266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        return count;
16366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
16466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey}
165