FreeRDP
SeparatedListAdapter.java
1 /*
2  Separated List Adapter
3  Taken from http://jsharkey.org/blog/2008/08/18/separating-lists-with-headers-in-android-09/
4 
5  Copyright Jeff Sharkey
6 
7  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
8  If a copy of the MPL was not distributed with this file, You can obtain one at
9  http://mozilla.org/MPL/2.0/.
10 */
11 
12 package com.freerdp.freerdpcore.utils;
13 
14 import android.content.Context;
15 import android.view.View;
16 import android.view.ViewGroup;
17 import android.widget.Adapter;
18 import android.widget.ArrayAdapter;
19 import android.widget.BaseAdapter;
20 
21 import com.freerdp.freerdpcore.R;
22 
23 import java.util.LinkedHashMap;
24 import java.util.Map;
25 
26 public class SeparatedListAdapter extends BaseAdapter
27 {
28 
29  public final static int TYPE_SECTION_HEADER = 0;
30  public final Map<String, Adapter> sections = new LinkedHashMap<>();
31  public final ArrayAdapter<String> headers;
32 
33  public SeparatedListAdapter(Context context)
34  {
35  headers = new ArrayAdapter<>(context, R.layout.list_header);
36  }
37 
38  public void addSection(String section, Adapter adapter)
39  {
40  this.headers.add(section);
41  this.sections.put(section, adapter);
42  }
43 
44  public void setSectionTitle(int section, String title)
45  {
46  String oldTitle = this.headers.getItem(section);
47 
48  // remove/add to headers array
49  this.headers.remove(oldTitle);
50  this.headers.insert(title, section);
51 
52  // remove/add to section map
53  Adapter adapter = this.sections.get(oldTitle);
54  this.sections.remove(oldTitle);
55  this.sections.put(title, adapter);
56  }
57 
58  public Object getItem(int position)
59  {
60  for (int i = 0; i < headers.getCount(); i++)
61  {
62  String section = headers.getItem(i);
63  Adapter adapter = sections.get(section);
64 
65  // ignore empty sections
66  if (adapter.getCount() > 0)
67  {
68  int size = adapter.getCount() + 1;
69 
70  // check if position inside this section
71  if (position == 0)
72  return section;
73  if (position < size)
74  return adapter.getItem(position - 1);
75 
76  // otherwise jump into next section
77  position -= size;
78  }
79  }
80  return null;
81  }
82 
83  public int getCount()
84  {
85  // total together all sections, plus one for each section header (except if the section is
86  // empty)
87  int total = 0;
88  for (Adapter adapter : this.sections.values())
89  total += ((adapter.getCount() > 0) ? adapter.getCount() + 1 : 0);
90  return total;
91  }
92 
93  public int getViewTypeCount()
94  {
95  // assume that headers count as one, then total all sections
96  int total = 1;
97  for (Adapter adapter : this.sections.values())
98  total += adapter.getViewTypeCount();
99  return total;
100  }
101 
102  public int getItemViewType(int position)
103  {
104  int type = 1;
105  for (int i = 0; i < headers.getCount(); i++)
106  {
107  String section = headers.getItem(i);
108  Adapter adapter = sections.get(section);
109 
110  // skip empty sections
111  if (adapter.getCount() > 0)
112  {
113  int size = adapter.getCount() + 1;
114 
115  // check if position inside this section
116  if (position == 0)
117  return TYPE_SECTION_HEADER;
118  if (position < size)
119  return type + adapter.getItemViewType(position - 1);
120 
121  // otherwise jump into next section
122  position -= size;
123  type += adapter.getViewTypeCount();
124  }
125  }
126  return -1;
127  }
128 
129  public boolean areAllItemsSelectable()
130  {
131  return false;
132  }
133 
134  public boolean isEnabled(int position)
135  {
136  return (getItemViewType(position) != TYPE_SECTION_HEADER);
137  }
138 
139  @Override public View getView(int position, View convertView, ViewGroup parent)
140  {
141  int sectionnum = 0;
142  for (int i = 0; i < headers.getCount(); i++)
143  {
144  String section = headers.getItem(i);
145  Adapter adapter = sections.get(section);
146 
147  // skip empty sections
148  if (adapter.getCount() > 0)
149  {
150  int size = adapter.getCount() + 1;
151 
152  // check if position inside this section
153  if (position == 0)
154  return headers.getView(sectionnum, convertView, parent);
155  if (position < size)
156  return adapter.getView(position - 1, null, parent);
157 
158  // otherwise jump into next section
159  position -= size;
160  }
161  sectionnum++;
162  }
163  return null;
164  }
165 
166  @Override public long getItemId(int position)
167  {
168  for (int i = 0; i < headers.getCount(); i++)
169  {
170  String section = headers.getItem(i);
171  Adapter adapter = sections.get(section);
172  if (adapter.getCount() > 0)
173  {
174  int size = adapter.getCount() + 1;
175 
176  // check if position inside this section
177  if (position < size)
178  return adapter.getItemId(position - 1);
179 
180  // otherwise jump into next section
181  position -= size;
182  }
183  }
184  return -1;
185  }
186 
187  public String getSectionForPosition(int position)
188  {
189  int curPos = 0;
190  for (int i = 0; i < headers.getCount(); i++)
191  {
192  String section = headers.getItem(i);
193  Adapter adapter = sections.get(section);
194  if (adapter.getCount() > 0)
195  {
196  int size = adapter.getCount() + 1;
197 
198  // check if position inside this section
199  if (position >= curPos && position < (curPos + size))
200  return section;
201 
202  // otherwise jump into next section
203  curPos += size;
204  }
205  }
206  return null;
207  }
208 }