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 com.google.android.collect.Lists;
2666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
2766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport java.util.ArrayList;
2866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
2966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey/**
3066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Adapter that combines multiple adapters as sections, asking each section to
3166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * provide a header, and correctly handling item types across child adapters.
3266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey */
3366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeypublic class SectionedListAdapter extends BaseAdapter {
3466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    private ArrayList<SectionAdapter> mSections = Lists.newArrayList();
3566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
3666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public interface SectionAdapter extends ListAdapter {
3766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        public View getHeaderView(View convertView, ViewGroup parent);
3866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
3966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
4066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public void clearSections() {
4166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        mSections.clear();
4266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        notifyDataSetChanged();
4366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
4466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
4554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey    /**
4654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey     * After mutating sections, you <em>must</em>
4754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey     * {@link AdapterView#setAdapter(android.widget.Adapter)} to correctly
4854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey     * recount view types.
4954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey     */
5066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public void addSection(SectionAdapter adapter) {
5166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        mSections.add(adapter);
5266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        notifyDataSetChanged();
5366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
5466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
5566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
5666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public int getCount() {
5766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        int count = 0;
5866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
5966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
6066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            count += mSections.get(i).getCount() + 1;
6166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
6266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        return count;
6366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
6466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
6566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
6666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public Object getItem(int position) {
6766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
6866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
6966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final SectionAdapter section = mSections.get(i);
7066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final int sectionSize = section.getCount() + 1;
7166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
7266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Check if position inside this section
7366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (position == 0) {
7466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return section;
7566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            } else if (position < sectionSize) {
7666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return section.getItem(position - 1);
7766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
7866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
7966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Otherwise jump into next section
8066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            position -= sectionSize;
8166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
8266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        throw new IllegalStateException("Unknown position " + position);
8366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
8466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
8566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
8666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public long getItemId(int position) {
8766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        return position;
8866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
8966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
9066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
9166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public View getView(int position, View convertView, ViewGroup parent) {
9266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
9366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
9466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final SectionAdapter section = mSections.get(i);
9566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final int sectionSize = section.getCount() + 1;
9666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
9766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Check if position inside this section
9866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (position == 0) {
9966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return section.getHeaderView(convertView, parent);
10066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            } else if (position < sectionSize) {
10166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return section.getView(position - 1, convertView, parent);
10266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
10366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
10466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Otherwise jump into next section
10566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            position -= sectionSize;
10666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
10766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        throw new IllegalStateException("Unknown position " + position);
10866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
10966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
11066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
11166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public boolean areAllItemsEnabled() {
11266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        return false;
11366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
11466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
11566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
11666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public boolean isEnabled(int position) {
11766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
11866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
11966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final SectionAdapter section = mSections.get(i);
12066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final int sectionSize = section.getCount() + 1;
12166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
12266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Check if position inside this section
12366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (position == 0) {
12466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return false;
12566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            } else if (position < sectionSize) {
12654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                return section.isEnabled(position - 1);
12766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
12866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
12966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Otherwise jump into next section
13066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            position -= sectionSize;
13166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
13266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        throw new IllegalStateException("Unknown position " + position);
13366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
13466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
13566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
13666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public int getItemViewType(int position) {
13766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        int type = 1;
13866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
13966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
14066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final SectionAdapter section = mSections.get(i);
14166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final int sectionSize = section.getCount() + 1;
14266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
14366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Check if position inside this section
14466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (position == 0) {
14566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return 0;
14666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            } else if (position < sectionSize) {
14766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                return type + section.getItemViewType(position - 1);
14866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
14966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
15066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            // Otherwise jump into next section
15166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            position -= sectionSize;
15266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            type += section.getViewTypeCount();
15366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
15466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        throw new IllegalStateException("Unknown position " + position);
15566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
15666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
15766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
15866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public int getViewTypeCount() {
15966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        int count = 1;
16066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final int size = mSections.size();
16166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        for (int i = 0; i < size; i++) {
16266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            count += mSections.get(i).getViewTypeCount();
16366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
16466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        return count;
16566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
16666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey}
167