Home | History | Annotate | Download | only in documentsui
      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 
     17 package com.android.documentsui;
     18 
     19 import android.view.View;
     20 import android.view.ViewGroup;
     21 import android.widget.AdapterView;
     22 import android.widget.BaseAdapter;
     23 import android.widget.ListAdapter;
     24 
     25 import 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  */
     31 public class SectionedListAdapter extends BaseAdapter {
     32     private ArrayList<SectionAdapter> mSections = new ArrayList<>();
     33 
     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 
     43     /**
     44      * After mutating sections, you <em>must</em>
     45      * {@link AdapterView#setAdapter(android.widget.Adapter)} to correctly
     46      * recount view types.
     47      */
     48     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) {
    124                 return section.isEnabled(position - 1);
    125             }
    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 }
    165