I am making a checklist type app in Android, in which I am populating items in a list view with a check box next to them. when a user clicks on an item I want it to strike out the text and update the entry in the database for the relevant column. For this reason I am storing Name-Value pairs in a TreeMap. Where Name corresponds to the Database Column Name and Value to the value in that Column name. I have achieved this using the following:
if ((c.getString(c.getColumnIndexOrThrow("Field130"))).length() > 3) {
String D11 = c.getString(c.getColumnIndexOrThrow("Field130"));
map.put("Field130", D11);
}
Now I want to display the name in one textview of the corresponding listview and value in the second textview. I tried the following:
ArrayList<TreeMap<String, String>> mylist = new ArrayList<TreeMap<String, String>>();
mylist.add(map);
ListView list = (ListView) findViewById(R.id.list);
ArrayList<String> list1 = new ArrayList<String>(map.values());
dataAdapter = new ArrayAdapter<String>(this,R.layout.chklistlayout,R.id.textView1, list1);
list.setAdapter(dataAdapter);
However I am not able to get the desired results, as I get only the Values displayed. Is there no way that I can map my TreeMap directly to the listview? I am open to ideas which are more robust, even if that means reworking my whole code.
I finally made a custom Adapter, took reference from here:
1) What adapter shall I use to use HashMap in a ListView
2) http://www.vogella.com/articles/AndroidListView/article.html.
3) http://www.youtube.com/watch?v=wDBM6wVEO70
4) https://dl.google.com/googleio/2010/android-world-of-listview-android.pdf
Edit: Based on suggestions in the comments, I have invoked a ViewHolder pattern to handle recycling of views and address the concerns of memory management and battery use. The complete code is as follows:
public class TreeMapAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
String[] mValues;
private TreeMap<String, String> mData = new TreeMap<String, String>();
private String[] mKeys;
public TreeMapAdapter(Context context, String[] mKeys,TreeMap<String, String> data) {
super(context, R.layout.chklistlayout, mKeys);
this.context = context;
this.values = mKeys;
mData = data;
mValues = mData.values().toArray(new String[data.size()]);
}
public int getCount() {
return mData.size();
}
public String getItem(int position) {
return mData.get(mKeys[position]);
}
public long getItemId(int arg0) {
return arg0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.chklistlayout,
parent, false);
holder = new ViewHolder();
holder.textView = (TextView) convertView.findViewById(R.id.textView1);
holder.imageview = (TextView) convertView.findViewById(R.id.textView2);
holder.CB = (CheckBox) convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(values[position]);
holder.imageview.setText(mValues[position]);
String s = mValues[position];
if (s.contains("h")) {
holder.CB.setChecked(true);
} else {
}
return convertView;
}
}
Following is the holder class:
static class ViewHolder {
TextView textView, imageview;
CheckBox CB;
}
There are three ways to recycle views, one is called as the Dumb way, the other as the right way and the one used in this example is the fastest way. Users who stumble on this post later, I highly recommend to go through the YouTube video. Its worth it!
In a nutshell ConvertView is responsible for recycling of views, it keeps track of all the views which are moving out of screen focus and returns one view which is recycled and reused.
Lastly Thanks to KMDev, who sparked this thought of researching more and making a template for Holder pattern.
来源:https://stackoverflow.com/questions/18532850/treemap-to-listview-in-android