I have an application that fetches announcements stored as xml files on a server and loads the title and author of each announcement into a ListView item. What I also need to store with each item is the ID of each announcement but I don't actually need to display it. I thought about maybe storing the ID in the hash map I use to fill the list and then find the associated ID with the title clicked but I think it would be unsafe to use since two announcements could have the same title (and author and date). I also thought about adding an invisible TextView to each item to store the ID but that was causing layout problems. Lastly, I searched around and found setTag() and getTag() which I think would be perfect for what I want to do but I'm not really sure how to use them with SimpleAdapter (I'm relatively new to this...). If the TextView idea is what I need to do (though I doubt it), here is the layout I'm using for each item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@android:id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<LinearLayout
android:orientation="horizontal"
android:id="@+id/items"
android:weightSum="100"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_weight="85"/>
<LinearLayout
android:orientation="vertical"
android:id="@+id/itemCB"
android:layout_weight="15"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<CheckBox
android:id="@+id/cbSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
And I'm using the following adapter to fill the list:
for(int i = 0; i < ann.length; i++)
{
map = new HashMap<String, String>();
map.put("line1", ann[i].getTitle());
map.put("line2", "Posted by: " + ann[i].getAuthor() + "\n" + ann[i].date.toLongString());
list.add(map);
}
String[] from = { "line1", "line2"};
int[] to = { android.R.id.text1, android.R.id.text2};
SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.twoline_checkbox_id_listitem, from, to);
setListAdapter(adapter);
Thank you for any help!
Theoretically you could do either approaches and it will probably work without problems. In the long run however, I would say you'll be better of with a simple entity object and a custom adapter. More specifically, from the looks of it, I would opt for an ArrayAdapter, and you already seem to be using some sort of simple entity object for the array ann
.
There are tons of examples that can show you how to extend ArrayAdapter. The most important part however is the getView()
method, which in it's most basic form could look somewhat like this:
public View getView(int position, View convertView, ViewGroup parent) {
View row;
if (null == convertView) {
row = mInflater.inflate(R.layout.list_item, null);
} else {
row = convertView;
}
MyObject item = (MyObject) getItem(position);
TextView tv = (TextView) row.findViewById(android.R.id.xxx);
tv.setText(item.getTitle);
// same for other fields/views; e.g. author, date etc
return row;
}
In stead of creating a SimpleAdapter, now create an instance of your CustomAdapter, pass it your array (or list) of entity objects, and set the whole as adapter to your list:
MyObject[] objects = ...
setListAdapter(new ArrayAdapter<string>(this, R.layout.list_item, objects));
Since you're now dealing with the objects directly, in stead of first creating a bunch of strings representation out of the different fields, you can also easily access the 'id' of every item. Even better, you can add a whole lot of different fields without worrying how it will look like in the list, since the visual representation is determined by what you set (and don't set) in the getView()
method of your adapter.
I just want to explain in little more detail answer of MH.
In your myArrayAdapter
class in getView
function you can assign your ID to the View
(which actually means "row") like this:
public View getView(int position, View convertView, ViewGroup parent){
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(mItemLayout, null);
}
String[] dataForOneRow = this.allRowsData.get(position);
// Tag is expected to be an Object (Integer is an object)
// our data are in String array - that's why we need to convert it into Integer
// I assume here, your ID number is first item (No.0) in the array of data
v.setTag(new Integer( Integer.valueOf(dataForOneRow[0]) ));
/*
...here you will set your data to display in your TextViews...
*/
return v;
}
And then you need to know the ID of the row when (for example) user clicked on the row and some detailed Activity is going to start.
I have my ListView
in the Fragment
and this is the piece of code from my main Activity
, from the declaration of Fragment
, placed in the function onCreateView
:
// here we assign "onClick listener" when user clicks a row
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent myRowClickIntent = new Intent(getActivity(), myDetailActivity.class);
// we can send some data to the new Activity through "extras"
// remember - our Tag is an object (Integer object) but putExtra() awaits some integer or string or some other type
// so here we are saying that it should be understood/treated as an Integer
myRowClickIntent.putExtra("item_id", (Integer)view.getTag() );
startActivity(myRowClickIntent);
}
});
And finally here is piece of code from onCreate
method of my DetailActivity:
Bundle myExtras;
int myItemId;
myExtras = getIntent().getExtras();
if (myExtras != null) {
myItemId = myExtras.getInteger("item_id");
}
Hope it helps somebody... :)
I'm also new to Android.
Big thank you
to StackOverflow for such help in learning Android development :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With