Your kind of data modeling and representation can be modeled in Java code as a LinkedHashMap<String, List<Data>>
, where Data
could look like:
public class Data {
private int id;
private String col1;
private String col2;
public Data(int id, String col1, String col2) {
this.id = id;
this.col1 = col1;
this.col2 = col2;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(id).append(", ").append(col1).append(", ").append(col2);
return sb.toString();
}
}
Why LinkedHasMap
? Because you need to preserve the order in which you insert the data. So your SQLite reading method could look like this:
public LinkedHashMap<String, List<Data>> readData(SQLiteDatabase db) {
LinkedHashMap<String, List<Data>> result = new LinkedHashMap<String, List<Data>>();
Cursor cursor = null;
try {
cursor = db.query("MY_TABLE", new String[] {
"datetime", "id", "col1", "col2"
}, null, null, null, null, "datetime, id ASC");
while (cursor.moveToNext()) {
String dateTime = cursor.getString(cursor.getColumnIndex("datetime"));
int id = cursor.getInt(cursor.getColumnIndex("id"));
String col1 = cursor.getString(cursor.getColumnIndex("col1"));
String col2 = cursor.getString(cursor.getColumnIndex("col2"));
List<Data> list = null;
if (result.containsKey(dateTime)) {
list = result.get(dateTime);
} else {
list = new ArrayList<Data>();
result.put(dateTime, list);
}
list.add(new Data(id, col1, col2));
}
} catch (Exception ex) {
Log.e("TAG", null, ex);
} finally {
if (cursor != null) {
cursor.close();
}
}
return result;
}
A basic adapter would look like this:
public class ExpAdapter extends BaseExpandableListAdapter {
private LinkedHashMap<String, List<Data>> input;
private LayoutInflater inflater;
public ExpAdapter(LayoutInflater inflater, LinkedHashMap<String, List<Data>> input) {
super();
this.input = input;
this.inflater = inflater;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return getChildData(groupPosition, childPosition);
}
private Data getChildData(int groupPosition, int childPosition) {
String key = getKey(groupPosition);
List<Data> list = input.get(key);
return list.get(childPosition);
}
private String getKey(int keyPosition) {
int counter = 0;
Iterator<String> keyIterator = input.keySet().iterator();
while (keyIterator.hasNext()) {
String key = keyIterator.next();
if (counter++ == keyPosition) {
return key;
}
}
// will not be the case ...
return null;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return getChildData(groupPosition, childPosition).getId();
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
TextView simpleTextView = null;
if (convertView == null) {
// inflate what you need, for testing purposes I am using android
// built-in layout
simpleTextView = (TextView) inflater.inflate(android.R.layout.simple_list_item_1,
parent, false);
} else {
simpleTextView = (TextView) convertView;
}
Data data = getChildData(groupPosition, childPosition);
simpleTextView.setText(data.toString());
return simpleTextView;
}
@Override
public int getChildrenCount(int groupPosition) {
String key = getKey(groupPosition);
return input.get(key).size();
}
@Override
public Object getGroup(int groupPosition) {
return getKey(groupPosition);
}
@Override
public int getGroupCount() {
return input.size();
}
@Override
public long getGroupId(int groupPosition) {
return 0;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
TextView simpleTextView = null;
if (convertView == null) {
// inflate what you need, for testing purposes I am using android
// built-in layout
simpleTextView = (TextView) inflater.inflate(android.R.layout.simple_list_item_1,
parent, false);
} else {
simpleTextView = (TextView) convertView;
}
simpleTextView.setText(getKey(groupPosition));
return simpleTextView;
}
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
While its simple use in a basic activity would be something like this:
public class MyExpandableActivity extends FragmentActivity {
private ExpandableListView expListView;
@Override
protected void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.expandable_layout);
expListView = (ExpandableListView) findViewById(R.id.exp_listview);
fillList();
}
private void fillList() {
LinkedHashMap<String, List<Data>> input = getMockList(); // get the collection here
ExpAdapter adapter = new ExpAdapter(LayoutInflater.from(this), input);
expListView.setAdapter(adapter);
}
}
Activity's simple layout:
<ExpandableListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/exp_listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Makes sense?
BaseExpandableListAdapter
if you say ok let i explain – CochleaBaseExpandableListAdapter
but please explain if you can. – DexterExpandableListView
working. – Dexter