Android: SeperatedList (How to get address book effect?) - android

Hallo All,
I have a ListView, which kontains a RadioGroup and a Button in each row. The ListView works well. Now i want to add a header to the ListView, to get the effect like the address book. I fund a Java Class from the Internet, which looks like this:
package com.aiquan.android.wljs_ncre3_free;
import java.util.LinkedHashMap;
import java.util.Map;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
public class SeparatedListAdapter extends BaseAdapter {
public final Map<String, Adapter> sections = new LinkedHashMap<String, Adapter>();
public final ArrayAdapter<String> headers;
public final static int TYPE_SECTION_HEADER = 0;
public SeparatedListAdapter(Context context) {
headers = new ArrayAdapter<String>(context, R.layout.list_header);
}
public void addSection(String sectionHeader, Adapter sectionAdapter) {
this.headers.add(sectionHeader);
this.sections.put(sectionHeader, sectionAdapter);
}
public Object getItem(int position) {
for (Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if (position == 0)
return section;
if (position < size)
return adapter.getItem(position - 1);
// otherwise jump into next section
position -= size;
}
return null;
}
public int getCount() {
// total together all sections, plus one for each section header
int total = 0;
for (Adapter adapter : this.sections.values())
total += adapter.getCount() + 1;
return total;
}
public int getViewTypeCount() {
// assume that headers count as one, then total all sections
int total = 1;
for (Adapter adapter : this.sections.values())
total += adapter.getViewTypeCount();
return total;
}
public int getItemViewType(int position) {
int type = 1;
for (Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if (position == 0)
return TYPE_SECTION_HEADER;
if (position < size)
return type + adapter.getItemViewType(position - 1);
// otherwise jump into next section
position -= size;
type += adapter.getViewTypeCount();
}
return -1;
}
public boolean areAllItemsSelectable() {
return false;
}
public boolean isEnabled(int position) {
return (getItemViewType(position) != TYPE_SECTION_HEADER);
}
// #Override
public View getView(int position, View convertView, ViewGroup parent) {
int sectionnum = 0;
for (Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if (position == 0)
return headers.getView(sectionnum, convertView, parent);
if (position < size)
return adapter.getView(position - 1, convertView, parent);
// otherwise jump into next section
position -= size;
sectionnum++;
}
return null;
}
// #Override
public long getItemId(int position) {
return position;
}
}
I try to use this class (without any change) to solve my problem. But i got a very strange effect: the part with RadioGroup and Buttons are not displayed, but the part with Strings are displayed correctly! And i got no error messages from Eclipse. Here is my code:
SeparatedListAdapter adapter = new SeparatedListAdapter(this);
adapter.addSection("Header 1", new ArrayAdapter<String>(this,
R.layout.list_item, new String[] { "First item", "Item two" }));
adapter.addSection("Header 2", new ExerciseAdapter(this,
R.layout.sc_for_exam, n_exercises));
adapter.addSection("Header 3", new ArrayAdapter<String>(this,
R.layout.list_item, new String[] { "lala", "lolo" }));
setListAdapter(adapter);
n_exercises ist an ArrayList, which contains the List Items(each list item contains a RadioGroup and a Button). ExerciseAdapter extends from ArrayAdapter.
Now i got this effect:
Does anybody know what is wrong and how i can solve this problem? Thank you very much!!
Here is the code of ExerciseAdapter. They are in the same class like the code above.
private class ExerciseAdapter extends ArrayAdapter<Exercise_SC> {
public ExerciseAdapter(Context context, int textViewResourceId,
ArrayList<Exercise_SC> exes) {
super(context, textViewResourceId, exes);
}
public View getView(final int position, View convertView,
ViewGroup parent) {
View row = convertView;
SC_ViewWrapper wrapper;
RadioGroup rg;
if (row == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (ChooseMode_Act.modeInfo.equalsIgnoreCase("Training")) {
row = vi.inflate(R.layout.sc_for_training, parent, false);
} else {
row = vi.inflate(R.layout.sc_for_exam, parent, false);
}
wrapper = new SC_ViewWrapper(row);
row.setTag(wrapper);
rg = wrapper.getRadioGroup();
RadioGroup.OnCheckedChangeListener l = new RadioGroup.OnCheckedChangeListener() {
// #Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
Integer myPosition = (Integer) group.getTag();
Exercise_SC eRow = getExerciseRow(myPosition);
eRow.setCheckedRB(checkedId);
switch (checkedId) {
case R.id.RB_A:
n_exercises.get(myPosition).setCustomerAnswer("A");
break;
case R.id.RB_B:
n_exercises.get(myPosition).setCustomerAnswer("B");
break;
case R.id.RB_C:
n_exercises.get(myPosition).setCustomerAnswer("C");
break;
case R.id.RB_D:
n_exercises.get(myPosition).setCustomerAnswer("D");
break;
default:
n_exercises.get(myPosition).setCustomerAnswer("");
}
}
};
rg.setOnCheckedChangeListener(l);
} else {
wrapper = (SC_ViewWrapper) row.getTag();
rg = wrapper.getRadioGroup();
}
Exercise_SC myExe = getExerciseRow(position);
int size = ChooseMode_Act.size;
wrapper.getTi().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getTVExer().setText(myExe.getExerciseText());
wrapper.getTVExer().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getA().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getTVA().setText(myExe.getAnswerA());
wrapper.getTVA().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getB().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getTVB().setText(myExe.getAnswerB());
wrapper.getTVB().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getC().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getTVC().setText(myExe.getAnswerC());
wrapper.getTVC().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getD().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getTVD().setText(myExe.getAnswerD());
wrapper.getTVD().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getImageView().setImageResource(myExe.getImageSrc());
if (ChooseMode_Act.modeInfo.equalsIgnoreCase("Training")) {
wrapper.getButton().setOnClickListener(new OnClickListener() {
// #Override
public void onClick(View v) {
Toast toast = Toast.makeText(
getApplicationContext(),
"题-"
+ (position + 1)
+ ": "
+ n_exercises.get(position)
.getCorrectAnswer(),
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
});
}
rg.setTag(new Integer(position));
rg.check(myExe.getCheckedRB());
return row;
}
}

IMO SeparatedListAdapter.getView(...) looks suspicious. Put logging on it (or debug) to study how it works and what it returns. Looks like it never returns a View from ExerciseAdapter.
UPDATE: on a second thought I realized it does call ExerciseAdapter for a View. So probably focus on what ExerciseAdapter.getView(...) returns being called from the SeparatedListAdapter.getView(...) context. Also could you post the ExerciseAdapter code?

Try this:
public int getViewTypeCount() {
// assume that headers count as one, then total all sections
//int total = 1;
//int total = 0;
int total = headers.getCount() + 1;
for (Adapter adapter : this.sections.values())
//total += adapter.getViewTypeCount();
total += (adapter.getCount() + 10);
return total;
}
Don't know why but it worked for me. I read a tip from some other question that getItemViewType() couldn't be greater than getViewTypeCount().

Related

Why I get UnsupportedOperationException in android?

public class SeparatedListAdapter extends BaseAdapter {
public final Map<String,Adapter> sections = new LinkedHashMap<String,Adapter>();
public final ArrayAdapter<String> headers;
public final static int TYPE_SECTION_HEADER = 0;
public SeparatedListAdapter(Context context) {
headers = new ArrayAdapter<String>(context, R.layout.list_header);
}
public void addSection(String section, Adapter adapter) {
this.headers.add(section);
this.sections.put(section, adapter); }
public Object getItem(int position) {
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position <= 0) return section;
if(position < size){
return adapter.getItem(position - 1);
}
// otherwise jump into next section
position -= size;
}
return null;
}
public int getCount() {
// total together all sections, plus one for each section header
int total = 0;
for(Adapter adapter : this.sections.values())
total += adapter.getCount() + 1;
return total;
}
public int getViewTypeCount() {
// assume that headers count as one, then total all sections
int total = 1;
for(Adapter adapter : this.sections.values())
total += adapter.getViewTypeCount();
return total;
} public int getItemViewType(int position) {
int type = 1;
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1; // check if position inside this section
if(position == 0) return TYPE_SECTION_HEADER;
if(position < size) return type + adapter.getItemViewType(position - 1);
// otherwise jump into next section
position -= size;
type += adapter.getViewTypeCount();
}
return -1;
}
#Override public View getView(int position, View convertView, ViewGroup parent) {
int sectionnum = 0;
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position == 0) return headers.getView(sectionnum, convertView, parent);
Here is an Exception
if(position < size) return adapter.getView(position - 1, convertView, parent);
// otherwise jump into next section
position -= size;
sectionnum++;
}
return null;
}
I don't understand why i get this exception in this line...Please Help me~
I heard this problem causes by List<> but, I couldn't find what is wrong in my coding
Where are you assigning a value to headers? What's most likely happening is that this is a ArrayAdapter backed by a read-only ArrayList.
This can happen for example when you run
this.headers = new ArrayAdapter(context, resource, Arrays.asList(T... array))
which returns a custom Array.ArrayList that is read-only. See here for asList documentation:
Returns a fixed-size list backed by the specified array.
This means you cannot run a .add() method on the list. For solution, see this related StackOverflow question.

setListItemChecked not highlighting all of the list items

Situation
I have a muliple choice mode ListView with two view types- normal and header. I load the data from the contacts app by retrieving a cursor with the names and emails and make use of the AlphabetIndexer class. My adapter extends the SimpleCursorAdapter class and implements the SectionIndexer. Moreover I override the getCount() method of my adapter so that it returns the count of the cursor + the count of the sections. In addition, my layouts are correct and items highlight in the onListItemClickListener, according to the user actions.
Problem
However, I want to highlight all the items with a Check All Button but the code fails to do that.
for (int i = 0; i <= adapter.getCount() - 1; i++) {
adapter.getItem(i);
if (adapter.getItemViewType(i) == InviteContactListAdapter.TYPE_NORMAL) {
listView.setItemChecked(i, true);
}
}
It changes correctly the layout of the items with position smaller than the cursror.getCount() and then refuses to mark the rest with a bigger index.I log the ListView.getCheckedItemPositions()
and this list includes all the items, including the ones whose layout has not been checked.
Log.d("checkedItems:", listView.getCheckedItemPositions()):
So their state is changed but not their layout.
Example
I have a list with 55 contacts and 20 section headers. When i run the Select All Button items with position 0... 55 get highlighted. Items from 56 to 75 get only get checked, not highlighted.
Code
public class InviteContactListAdapter extends SimpleCursorAdapter implements
SectionIndexer {
public static final int TYPE_HEADER = 1;
public static final int TYPE_NORMAL = 0;
public static final int TYPE_COUNT = 2;
private AlphabetIndexer indexer;
private int[] usedSectionNumbers;
private Map<Integer, Integer> sectionToPosition;
private Context context;
private HashMap<Integer, Integer> sectionToOffset;
public InviteContactListAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to, 0);
ArrayList<String> stringCollection = new ArrayList<String>();
Character firstLetter;
String firstLetterAsString;
while (c.moveToNext()) {
firstLetter = c.getString(
c.getColumnIndex(ContactsContract.Data.DISPLAY_NAME))
.charAt(0);
firstLetter = Character.toUpperCase(firstLetter);
firstLetterAsString = firstLetter.toString();
if (!stringCollection.contains(firstLetterAsString)
&& Character.isLetter(firstLetter)) {
stringCollection.add(firstLetterAsString);
}
}
Collections.sort(stringCollection);
String alphabet = " ";
for (String s : stringCollection) {
alphabet = alphabet + s;
}
c.moveToFirst();
Log.d("length", "" + alphabet.length());
this.context = context;
indexer = new AlphabetIndexer(c,
c.getColumnIndexOrThrow(ContactsContract.Data.DISPLAY_NAME),
alphabet);
sectionToPosition = new TreeMap<Integer, Integer>();
sectionToOffset = new HashMap<Integer, Integer>();
final int count = super.getCount();
int i;
for (i = count - 1; i >= 0; i--) {
sectionToPosition.put(indexer.getSectionForPosition(i), i);
}
i = 0;
usedSectionNumbers = new int[sectionToPosition.keySet().size()];
for (Integer section : sectionToPosition.keySet()) {
sectionToOffset.put(section, i);
usedSectionNumbers[i] = section;
i++;
}
for (Integer section : sectionToPosition.keySet()) {
sectionToPosition.put(section, sectionToPosition.get(section)
+ sectionToOffset.get(section));
}
Log.d("", "");
}
#Override
public int getCount() {
if (super.getCount() != 0) {
return super.getCount() + usedSectionNumbers.length;
}
return 0;
}
#Override
public Object getItem(int position) {
if (getItemViewType(position) == TYPE_NORMAL) {
return super.getItem(position
- sectionToOffset.get(getSectionForPosition(position)) - 1);
}
return null;
}
#Override
public int getPositionForSection(int section) {
if (!sectionToOffset.containsKey(section)) {
int i = 0;
int maxLength = usedSectionNumbers.length;
while (i < maxLength && section > usedSectionNumbers[i]) {
i++;
}
if (i == maxLength)
return getCount();
return indexer.getPositionForSection(usedSectionNumbers[i])
+ sectionToOffset.get(usedSectionNumbers[i]);
}
return indexer.getPositionForSection(section)
+ sectionToOffset.get(section);
}
#Override
public int getSectionForPosition(int position) {
int i = 0;
int maxLength = usedSectionNumbers.length;
while (i < maxLength
&& position >= sectionToPosition.get(usedSectionNumbers[i])) {
i++;
}
return usedSectionNumbers[i - 1];
}
#Override
public Object[] getSections() {
return indexer.getSections();
}
// nothing much to this: headers have positions that the sectionIndexer
// manages.
#Override
public int getItemViewType(int position) {
if (position == getPositionForSection(getSectionForPosition(position))) {
return TYPE_HEADER;
}
return TYPE_NORMAL;
}
#Override
public int getViewTypeCount() {
return TYPE_COUNT;
}
// return the header view, if it's in a section header position
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final int type = getItemViewType(position);
LayoutInflater inflater = LayoutInflater.from(context);
if (type == TYPE_HEADER) {
if (convertView == null) {
convertView = inflater.inflate(
R.layout.list_item_alphabet_section_header, parent,
false);
}
((TextView) convertView.findViewById(R.id.letter_header))
.setText((String) getSections()[getSectionForPosition(position)]);
return convertView;
}
return super.getView(
position - sectionToOffset.get(getSectionForPosition(position))
- 1, convertView, parent);
}
// these two methods just disable the headers
#Override
public boolean areAllItemsEnabled() {
return false;
}
#Override
public boolean isEnabled(int position) {
if (getItemViewType(position) == TYPE_HEADER) {
return false;
}
return true;
}
EDIT
I think the issue might be that you are calling the super methods all over the place, which in my opinion means that the default behavior of the SimpleCursorAdapter has (which includes highlighting a selection) only applies to the first size of the cursor items.
In other words, highlighting a selected row is not a default "feature" of an Adapter, but rather something you must implement explicitly.
While the SimpleCursorAdapter has the highlighting "built-in", it only does so for a number of items equal to the Cursor's size.
I don't see how you can change this, other than managing the views yourself manually in the getView method (i.e. do the highlighting yourself by changing the background of the views).

Using complex header layouts in listview

I have an android app that populates a listview with a custom adapter. This adapter adds sections to the listview with headers. This adapter is shown below:
public class SeparatedListAdapter extends BaseAdapter {
public final Map<String,Adapter> sections = new LinkedHashMap<String,Adapter>();
public final ArrayAdapter<String> headers;
public final static int TYPE_SECTION_HEADER = 0;
public SeparatedListAdapter(Context context) {
headers = new ArrayAdapter<String>(context, R.layout.list_header);
}
public void addSection(String section, Adapter adapter) {
this.headers.add(section);
this.sections.put(section, adapter);
}
public Object getItem(int position) {
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position == 0) return section;
if(position < size) return adapter.getItem(position - 1);
// otherwise jump into next section
position -= size;
}
return null;
}
public int getCount() {
// total together all sections, plus one for each section header
int total = 0;
for(Adapter adapter : this.sections.values())
total += adapter.getCount() + 1;
return total;
}
public int getViewTypeCount() {
// assume that headers count as one, then total all sections
int total = 1;
for(Adapter adapter : this.sections.values())
total += adapter.getViewTypeCount();
return total;
}
public int getItemViewType(int position) {
int type = 1;
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position == 0) return TYPE_SECTION_HEADER;
if(position < size) return type + adapter.getItemViewType(position - 1);
// otherwise jump into next section
position -= size;
type += adapter.getViewTypeCount();
}
return -1;
}
public boolean areAllItemsSelectable() {
return false;
}
public boolean isEnabled(int position) {
return (getItemViewType(position) != TYPE_SECTION_HEADER);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
int sectionnum = 0;
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position == 0) return headers.getView(sectionnum, convertView, parent);
if(position < size) return adapter.getView(position - 1, convertView, parent);
// otherwise jump into next section
position -= size;
sectionnum++;
}
return null;
}
#Override
public long getItemId(int position) {
return position;
}
}
Which is then called by the following code:
SeparatedListAdapter adapter;
public Map<String,?> createItem(String name) {
Map<String,String> item = new HashMap<String,String>();
item.put(ITEM_VALUE, name);
return item;
}
List<Map<String,?>> item = new LinkedList<Map<String,?>>();
item.add(createItem("value"));
adapter.addSection("Header", new SimpleAdapter(this, item, R.layout.list_item, new String[] { "value" }, new int[] { R.id.lblValue }));
listview.setAdapter(adapter);
Now until recently, my list_header xml file had a TextView root element. At this point it was working perfectly. But then I wanted to expand on the header to contain more than one view. The new root element of the list_header is now a RelativeLayout.
Now when I try and start the activity, I get the following exception: IllegalStateException: ArrayAdapter requires the resource ID to be a Text View. I understand the error but since I am relatively new to Android, I am unsure how to get around this problem. How can I modify my adapter to handle headers which contain a RelativeLayout as the root element, instead of a TextView?
Edit:
I believe the answer lies in the constructor method of the adapter?
Edit: I believe the answer lies in the constructor method of the
adapter?
Precisely, you should use this one:
headers = new ArrayAdapter<String>(context, R.layout.list_header, R.id.the_id_of_textview);
Also, have a look at this answer.

in android baseadapter, how to hide the section header when no item is in the section

I use component android-section-list to create sections in my listView, which is using the baseadapter.
The listView shows the artists, and each section groups the artists by their alphabet. Currently in my code, the sections range from a-z and 0-9. But in some cases, some sections do not have a item, therefore it is no need to show the section with no artists.
import java.util.LinkedHashMap;
import java.util.Map;
import android.content.Context;
import android.graphics.Typeface;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
public class SeparatedListAdapter extends BaseAdapter {
public final Map<String,Adapter> sections = new LinkedHashMap<String,Adapter>();
public final ArrayAdapter<String> headers;
public final static int TYPE_SECTION_HEADER = 0;
Typeface arialFont, folksFont;
String activity;
public SeparatedListAdapter(Context context) {
headers = new ArrayAdapter<String>(context, R.layout.list_header);
}
public void addSection(String section, Adapter adapter) {
this.headers.add(section);
this.sections.put(section, adapter);
}
public Object getItem(int position) {
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position == 0) return section;
if(position < size) return adapter.getItem(position - 1);
// otherwise jump into next section
position -= size;
}
return null;
}
public int getCount() {
// total together all sections, plus one for each section header
int total = 0;
for(Adapter adapter : this.sections.values())
total += adapter.getCount() + 1;
return total;
}
public int getViewTypeCount() {
// assume that headers count as one, then total all sections
int total = 1;
for(Adapter adapter : this.sections.values())
total += adapter.getViewTypeCount();
return total;
}
public int getItemViewType(int position) {
int type = 1;
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position == 0) return TYPE_SECTION_HEADER;
if(position < size) return type + adapter.getItemViewType(position - 1);
// otherwise jump into next section
position -= size;
type += adapter.getViewTypeCount();
}
return -1;
}
public boolean areAllItemsSelectable() {
return false;
}
public boolean isEnabled(int position) {
return (getItemViewType(position) != TYPE_SECTION_HEADER);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
int sectionnum = 0;
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position == 0) return headers.getView(sectionnum, convertView, parent);
if(position < size) return adapter.getView(position - 1, convertView, parent);
// otherwise jump into next section
position -= size;
sectionnum++;
}
return null;
}
public long getItemId(int position) {
return position;
}
}
so my question is how to hide the section header when the sections has no items to show, the change is on getView() methods or somewhere else

Jeff Sharkey Listview

I'm relatively new to Android and Java so forgive me if this is a stupid question. I'm using Jeff Sharkeys SeperatedListAdapter and I'd like to create a list like below, where it goes HEAD item_complex.xml, list_item.xml, item_complex.xml ANOTHER HEADER ...and so on but I'm failing to comprehend what needs to be done to achieve this. most likely due to my lack of android and java knowledge. Could someone help me out please?
if it helps...code...
package com.biosonik.iceland.news;
import java.util.LinkedHashMap;
import java.util.Map;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import com.biosonik.iceland_planner.R;
public class SeparatedListAdapter extends BaseAdapter {
public final Map<String,Adapter> sections = new LinkedHashMap<String,Adapter>();
public final ArrayAdapter<String> headers;
public final static int TYPE_SECTION_HEADER = 0;
public SeparatedListAdapter(Context context) {
headers = new ArrayAdapter<String>(context, R.layout.list_header);
}
public void addSection(String section, Adapter adapter) {
this.headers.add(section);
this.sections.put(section, adapter);
}
public Object getItem(int position) {
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position == 0) return section;
if(position < size) return adapter.getItem(position - 1);
// otherwise jump into next section
position -= size;
}
return null;
}
public int getCount() {
// total together all sections, plus one for each section header
int total = 0;
for(Adapter adapter : this.sections.values())
total += adapter.getCount() + 1;
return total;
}
#Override
public int getViewTypeCount() {
// assume that headers count as one, then total all sections
int total = 1;
for(Adapter adapter : this.sections.values())
total += adapter.getViewTypeCount();
return total;
}
#Override
public int getItemViewType(int position) {
int type = 1;
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position == 0) return TYPE_SECTION_HEADER;
if(position < size) return type + adapter.getItemViewType(position - 1);
// otherwise jump into next section
position -= size;
type += adapter.getViewTypeCount();
}
return -1;
}
public boolean areAllItemsSelectable() {
return false;
}
#Override
public boolean isEnabled(int position) {
return (getItemViewType(position) != TYPE_SECTION_HEADER);
}
public View getView(int position, View convertView, ViewGroup parent) {
int sectionnum = 0;
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if(position == 0) return headers.getView(sectionnum, convertView, parent);
if(position < size) return adapter.getView(position - 1, convertView, parent);
// otherwise jump into next section
position -= size;
sectionnum++;
}
return null;
}
public long getItemId(int position) {
return position;
}
}
Activity...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.planner_list);
List<Map<String,?>> security = new LinkedList<Map<String,?>>();
week34.add(createItem("62","Monday 19th Novermber","C1P1 Change-Over Day 1", "text text text text",String.valueOf(R.drawable.lsnow),"9C"));
week35.add(createItem("52","Monday 19th Novermber", "C1P1 Change-Over Day 2", "text text text text",String.valueOf(R.drawable.hsnow),"12C"));
// create our list and custom adapter
SeparatedListAdapter adapter = new SeparatedListAdapter(this);
adapter.addSection("Week 34",
new SimpleAdapter(DisplayNewsActivity.this, week34, R.layout.list_complex,
new String[] {ITEM_UID, ITEM_DATE, ITEM_HEADLINE, ITEM_GRAB_LINE, ITEM_WEATHER_TEMP, ITEM_WEATHER_ICON }, new int[] {R.id.uid, R.id.date, R.id.headline, R.id.grab_line,R.id.weather_icon,R.id.weather_temp }));
adapter.addSection("UNWANTED HEADER", new ArrayAdapter<String>(this,
R.layout.list_item, new String[] { "SIMPLE LIST ENTRY" }));
adapter.addSection("Week 35",
new SimpleAdapter(DisplayNewsActivity.this, week35, R.layout.list_complex,
new String[] {ITEM_UID, ITEM_DATE, ITEM_HEADLINE, ITEM_GRAB_LINE, ITEM_WEATHER_TEMP, ITEM_WEATHER_ICON }, new int[] {R.id.uid, R.id.date, R.id.headline, R.id.grab_line,R.id.weather_icon,R.id.weather_temp }));
list=(ListView)findViewById(R.id.list);
list.setAdapter(adapter);
In getViewTypeCount(), why does it assume that headers count as one? In the way I see this method, there would be two diferente kind of view for each section, so for example, with 2 sections you would have 4 types of view instead of 3 as it is being brought by this code (Apologies for my english)

Categories

Resources