show item in list view after sax xml parsing - android

I had done xml parsing and able to display one array item in list view .but i want to display 2 array item in one list...using array adapter..means i want array_barrio and array_ciudad both in one list view how can i do this...my java class is
public class XMLParsingExample extends ListActivity {
String name = null;
private String array_estado[];
private String[] array_ciudad;
private String array_barrio[];
/** Create Object For SiteList Class */
SitesList sitesList = null;
/** Called when the activity is first created. */
#SuppressWarnings("unchecked")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listplaceholder);
/** Create a new layout to display the view */
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
/** Send URL to parse XML Tags */
URL sourceUrl = new URL(
"http://www.arteonline.mobi/iphone/output.php?key=Buenos");
MyXMLHandler myXMLHandler = new MyXMLHandler();
xr.setContentHandler(myXMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
sitesList = MyXMLHandler.sitesList;
array_ciudad = new String[sitesList.getEstado().size()];
for (int i = 0; i < sitesList.getEstado().size(); i++)
{
name = sitesList.getEstado().get(i);
array_ciudad[i] = name;
Log.i("array_spinner" + i, array_ciudad[i]);
}
array_barrio = new String[sitesList.getBarrio().size()];
for (int i = 0; i < sitesList.getBarrio().size(); i++)
{
name = sitesList.getBarrio().get(i);
array_barrio[i] = name;
// Log.i("array_spinner" + i, array_ciudad[i]);
}
setListAdapter(new ArrayAdapter(this,
android.R.layout.simple_list_item_1, array_barrio));
// setListAdapter(new ArrayAdapter(this,
// android.R.layout.simple_list_item_1, array_barrio ));
}

You can make a new String[] that is big enough to hold both, and then copy the elements of each array to the new array. Use the new array in your ArrayAdapter.
String[] bigArray = new String[array_barrio.length + array_ciudad.length];
System.arraycopy(array_barrio, 0, bigArray, 0, array_barrio.length);
System.arraycopy(array_ciudad, array_barrio.length, bigArray, array_barrio.length, array_ciudad.length);
Another thing worth considering would be to just create the bigArray initially, and just add both sets of elements to the big array rather than the smaller ones.

Do you want to combine two array items and make it as one. then you can follow nicholas way . Add both the array and make it as one array and pass the array to ArrayAdapter. But if you want to display data of both arrays in the same list then you have to use BaseAdapter and write your own logic for that.
Thanks
Deepak

If you want to show more than one item in a list view item you can use your own Adapter by extending BaseAdapter. But first of array_ciudad and array_barrio would need to be the same size.
Each Item will need to be represented by a list item layout like the one below. This layout would need to be placed in the res/layout directory.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Location where barrio items will be displayed -->
<TextView android:id="#+id/barrio"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<!-- Location where ciudad items will be displayed -->
<TextView android:id="#+id/ciudad"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
This example custom adapter assumes that both array_barrio and array_ciudad will be the same length. All you really need to do is create the view for the list items by inflating the layout and inserting your Strings into the TextViews where needed. In this example MyAdapter should be an inner class of XMLParsingExample giving it direct access to the array properties you defined.
protected class MyAdapter extends BaseAdapter {
private LayoutInflater inflater;
public MyAdapter(Context ctx) {
super();
this.inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return XMLParsingExample.this.array_barrio.length;
}
/* Not implemented but not really needed */
#Override
public Object getItem(int position) {
return null;
}
/* Not implemented but not really needed */
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = inflater.inflate(R.layout.listitem_layout, parent, false);
Course c = courses.get(position);
String barrio = XMLParsingExample.this.array_barrio[position];
String ciudad = XMLParsingExample.this.array_ciudad[position];
TextView tv = (TextView) v.findViewById(R.id.barrio);
tv.setText(barrio);
tv = (TextView) v.findViewById(R.id.ciudad);
tv.setText(ciudad);
return v;
}
}

Related

how to create columns dynamically in android?

I am trying to make list view in android .I am able to make simple list view using static data .Now I take json file in asset folder . Then I read contend from json file and display on list view .It is working fine.
I do like this
public class MainActivity extends Activity {
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list_view);
Log.d("==", loadJSONFromAsset());
String arr[];
try {
JSONArray js = new JSONArray(loadJSONFromAsset());
arr = new String[js.length()];
for (int i = 0; i < js.length(); i++) {
JSONObject obj = js.getJSONObject(i);
arr[i] = obj.getString("name");
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,arr);
listView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
public String loadJSONFromAsset() {
String json = null;
try {
InputStream is = getAssets().open("data.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
}
It is working fine
But I need to do different task .I need to read json file from asset folder . and create as same number of column as in json array
This is new json file
{"coulmns":[
{
"name": "Test_1"
},
{
"name": "Test_2"
},
{
"name": "Test_3"
},
{
"name": "Test_4"
}
]}
I need to create four column of equal width (because there is four object).If it is three than it show three column of equal width .can we do in android ?
any idea..?
how to do with grid view ?
A GridView is a specific type of ListView that is designed to put your list into multiple columns, or a grid. It's just as easy to use as a ListView, except that you need to specify the number of columns you have. Try this:
Replace the instance of ListView in your XML file with GridView
Replace the ListView in your activity with GridView
Set the number of columns you want. You can make this dynamic by changing it depending on your data.
public class MainActivity extends Activity {
GridView gridView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (ListView) findViewById(R.id.grid_view);
Log.d("==", loadJSONFromAsset());
String arr[];
try {
JSONArray js = new JSONArray(loadJSONFromAsset());
arr = new String[js.length()];
for (int i = 0; i < js.length(); i++) {
JSONObject obj = js.getJSONObject(i);
arr[i] = obj.getString("name");
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,arr);
gridView.setAdapter(adapter);
gridview.setNumColumns(4);
//You can replace 4 with a formula if you want it to be variable
} catch (JSONException e) {
e.printStackTrace();
}
}
Also see: http://developer.android.com/reference/android/widget/GridView.html
Straight out of the box, the ArrayAdapter<MyObject> is going to populate only a TextView with values as defined by myObject.toString(). If you need a mode complex list item view you have to create your own adapter that extends ArrayAdapter and override getView(...).
For example, your adapter creation would be:
MyArrayAdapter adapter = new MyArrayAdapter(this,R.layout.my_list_item,arr);
I defined MyObject inside the adapter, but it could anywhere. The idea is that MyObject will consist of the texts from one "row" (all the column values)
A very raw version of your adapter could be:
public class MyArrayAdapter extends ArrayAdapter<MyArrayAdapter.MyObject> {
public MyArrayAdapter(Context context, int resource, ArrayList<MyObject> objects) {
super(context, resource, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item, parent, false);
viewHolder = new ViewHolder();
for (int i= 0; i < MyObject.MAX_COLUMNS; i++)
viewHolder.mTextViews[i] = (TextView)((ViewGroup)convertView).getChildAt(i);
convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder)convertView.getTag();
}
MyObject myObject = getItem(position);
for (int i = 0; i < myObject.myTexts.length; i++)
{
viewHolder.mTextViews[i].setVisibility(View.VISIBLE);
viewHolder.mTextViews[i].setText(myObject.myTexts[i]);
}
for (int i = myObject.myTexts.length; i < MyObject.MAX_COLUMNS; i++)
viewHolder.mTextViews[i].setVisibility(View.GONE);
return convertView;
}
private static class ViewHolder {
public TextView[] mTextViews = new TextView[MyObject.MAX_COLUMNS];
}
public static class MyObject {
public static int MAX_COLUMNS = 4;
public MyObject(String[] texts) {
myTexts = texts;
}
public String[] myTexts;
}
}
And your item layout (with four TextViews, but add/remove if your max columns is different):
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
</LinearLayout>
In case you don't have a way to know the max number of your columns, you have to construct the item layout dynamically instead of inflating it from a resource and more importantly the ViewHolder pattern is pretty much useless.

Android add items to arraylist using custom class

I'm trying to add items to an arraylist using this class template:
public class Template {
public String username;
public String email;
}
Here's the whole code:
public void JsonToArrayList(JSONArray myJsonArray) throws JSONException
{
ArrayList<Template> listItems = new ArrayList<Template>();
JSONObject jo = new JSONObject();
Template tem = new Template();
ListView lv = (ListView) findViewById(R.id.listView1);
for(int i = 0; i<myJsonArray.length(); i++)
{
jo = myJsonArray.getJSONObject(i);
tem.username = jo.getString("username");
tem.email = jo.getString("user_email");
listItems.add(tem);
Log.e("Ninja Archives", tem.username);
}
// This is the array adapter, it takes the context of the activity as a first // parameter, the type of list view as a second parameter and your array as a third parameter
ArrayAdapter<Template> arrayAdapter = new ArrayAdapter<Template>(this,android.R.layout.simple_list_item_1, listItems);
lv.setAdapter(arrayAdapter);
}
The problem is, instead of filling my listview with nice username and email strings, it's filling up with items like this:
com.android.ninjaarchives.
Template#40585690
I think somewhere along the line I have become lost, but I've been trying all sorts for ages now and getting nowhere. Can anyone point me in the right direction?
Thanks for any help.
Note: not really sure what's going on with the code; it doesn't appear to be pasting correctly.
Use below code, it can be a solution for you
public void JsonToArrayList(JSONArray myJsonArray) throws JSONException
{
ArrayList<Template> listItems = new ArrayList<Template>();
JSONObject jo = new JSONObject();
Template tem = new Template();
ListView lv = (ListView) findViewById(R.id.listView1);
String listItemString[] = new String[myJsonArray.length];
for(int i = 0; i<myJsonArray.length(); i++)
{
jo = myJsonArray.getJSONObject(i);
tem.username = jo.getString("username");
tem.email = jo.getString("user_email");
listItemString[i] = tem.username +" - " + tem.email; // u can change it according to ur need.
listItems.add(tem);
Log.e("Ninja Archives", tem.username);
}
// This is the array adapter, it takes the context of the activity as a first // parameter, the type of list view as a second parameter and your array as a third parameter
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, listItemString);
lv.setAdapter(arrayAdapter);
}
But better to write Custom adapter by extending BaseAdapter, and do listItem handling in getView method here is one simple tutorial
Take a class extending Base
private class CustomAdapter extends BaseAdapter
{
LayoutInflater inflater;
public CustomAdapter(Context context)
{
inflater = LayoutInflater.from(context);
}
public int getCount()
{
return listItems.size();
}
public Object getItem(int position)
{
return listItems.get(position);
}
public long getItemId(int position)
{
return position;
}
public View getView(final int position, View convertView,ViewGroup parent)
{
//if(convertView==null)
//convertView = inflater.inflate(R.layout.listlayout, parent, false);
Template data = (Template) getItem(position);
TextView v=new TextView(context);
v.setText(data.name);
return v;
}
}
and set adapter to your listview
lv.setAdapter(new CustomAdapter(this));
In this case you have to use a custom adapter (that extends from ArrayAdapter) and override the getView method to display in a custom layout the username and the email.

two custom listview in one listactivity

So, so far i built a list of json object like this
public class list extends ListActivity{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
Intent i = getIntent();
String snopel = i.getStringExtra("nopel");
String snama = i.getStringExtra("nama");
String salamat = i.getStringExtra("alamat");
String sgolongan = i.getStringExtra("golongan");
TextView tx_nopel = (TextView)findViewById(R.id.l_nopel);
TextView tx_nama= (TextView)findViewById(R.id.l_nama);
TextView tx_alamat = (TextView)findViewById(R.id.l_alamat);
TextView tx_golongan = (TextView)findViewById(R.id.l_golongan);
tx_nopel.setText(snopel);
tx_nama.setText(snama);
tx_alamat.setText(salamat);
tx_golongan.setText(sgolongan);
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
pairs.add(new BasicNameValuePair("nopel", snopel));
ArrayList<HashMap<String, String>> lr = new ArrayList<HashMap<String, String>>();
JSON json_lr = new JSON();
JSONObject jobj_lr = json_lr.getJSON("http://10.0.2.2/KP/pdam/listtagihan.php", pairs);
try {
int length = jobj_lr.getInt("panjang");
for(int n = 1; n <= length; n++){
String m = Integer.toString(n);
JSONObject row = jobj_lr.getJSONObject(m);
String snomor = row.getString("nomor");
String sbulan = row.getString("bulan");
String stahun = row.getString("tahun");
String stagihan = "Rp. " + row.getString("tagihan");
HashMap<String, String> rek = new HashMap<String, String>();
rek.put("nomor", snomor);
rek.put("bulan", sbulan);
rek.put("tahun", stahun);
rek.put("tagihan", stagihan);
lr.add(rek);
}
} catch (JSONException e) {
e.printStackTrace();
}
ListAdapter adapter_lr = new SimpleAdapter(this, lr, R.layout.list_data,
new String[]{"nomor","bulan","tahun","tagihan"},
new int[]{R.id.textView1, R.id.textView2, R.id.textView3, R.id.textView4});
setListAdapter(adapter_lr);
ListView lv_lr = getListView();
lv_lr.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Intent i = new Intent(list.this, rincian.class);
i.putExtra("nomor", ((TextView)view.findViewById(R.id.textView1)).getText().toString());
startActivity(i);
}
});
}
}
that will show one listview in one listactivity, but I wonder if I can make 2 custom listviews in 1 list activity, but I can't figure out how to
I think that it's impossible because in listactivity we must set the adapter that can just choose 1 list adapter like this setListAdapter(adapter_lr);
but I want to know for sure is it true?
Thanks in advance.
why you need two listview in one Activity ?
if you want two listview then you can extends Activity and add two listview in layout file.
Now,
ListView listView1=(ListView)findViewById(R.id.listview1);
ListView listView2=(ListView)findViewById(R.id.listview2);
You can create two custom list view in one list activity by declaring them in xml file
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="Value in dps"
></ListView>
<ListView
android:id="#+id/list1"
android:layout_width="fill_parent"
android:layout_height="Value in dps"
></ListView>
one list id must be #android:id/list other can be anything of yor choice and you can set adapters as you want in code.
You need to extend Activity class in YourClass, and you can have as many List view from layout.

Android - ListView dynamic Buttons for each row calling dynamic listeners

I'm new to android, i've spent the last 2 days trying previous examples and online solutions but I just can't seem to get my head around it :(
I'm able to display a list view, parse some json from online and store a book title, book description and book ID and display this data in the listview. I want to be able to put a 'download' button in each row for the ListView, each button will correspond to its book ID on Click() and the action listener will download the book by appending that ID to a url.
e.g www.books.com/download_book1 or /download_book2....
Here is my code. Catalogue.java class
public class Catalogue extends ListActivity {
private JSONObject json;
private ListView lv;
private ArrayList<Integer> alKey = new ArrayList<Integer>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //icicle
setContentView(R.layout.shelflist);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
....
try{
JSONArray entries = json.getJSONArray("entries");
for(int i=0;i<entries.length();i++){
HashMap<String, String> map = new HashMap<String, String>();
JSONObject e = entries.getJSONObject(i);
alKey.add(e.getInt("key"));
map.put("id", String.valueOf(i));
map.put("title", "Title:" + e.getString("title"));
map.put("description", "Description: " + e.getString("description"));
mylist.add(map);
}
}catch(JSONException e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.shelfrow,
new String[] { "title", "description" },
new int[] { R.id.item_title, R.id.item_subtitle });
setListAdapter(adapter);
lv = getListView();
lv.setTextFilterEnabled(true);
.....
This is as far as I get. I don't know how to add 1 button per row in the List and assign an action listener to each button.
I also have a shelfrow.xml file (textView, textView for item_title and item_subtitle) and a shelflist.xml file (ListView).
I have a shelf.xml file with
Basically you need to learn the concept of ListAdapter.
Here's the short story: picture an object that holds the data to be displayed inside a list, along with the way to display each line individually. That's your ListAdapter. Now take each individual line: it's a book with a title and an OnClickListener. It's rendered inside a View with a TextView (for the title) and a Button (for the OnClickListener). All you need to do is give one View to the adapter that will be used for each line, and a List of the books you want to be inside the list.
Here's some sample code. I hope it clears things up a bit
private class MyItemModel{ //that's our book
String title; // the book's title
String description;
long id;
OnClickListener listener = new OnClickListener(){ // the book's action
#Override
public void onClick(View v) {
// the default action for all lines
doSomethingWithTheBookTitleOrUniqueId(this);
}
};
}
private class MyListAdapter extends BaseAdapter{
View renderer;
List<MyItemModel> items;
// call this one and pass it layoutInflater.inflate(R.layout.my_list_item)
public MyListAdapter(View renderer) {
this.renderer = renderer;
}
// whenever you need to set the list of items just use this method.
// call it when you have the data ready and want to display it
public void setModel(List<MyItemModel> items){
this.items = items;
notifyDataSetChanged();
}
#Override
public int getCount() {
return items!=null?items.size():0;
}
#Override
public Object getItem(int position) {
return items!=null?items.get(position):null;
}
#Override
public long getItemId(int position) {
return items!=null?items.get(position).id:-1;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
convertView = renderer;
}
MyItemModel item = items.get(position);
// replace those R.ids by the ones inside your custom list_item layout.
TextView label = (TextView)convertView.findViewById(R.id.item_title);
label.setText(item.label);
Button button = (Button)convertView.findViewById(R.id.item_button);
button.setOnClickListener(item.listener);
return convertView;
}
}
In order to pass the List, instead of putting the data inside your list of hashmaps you can do this for instance (be careful, I also updated the MyItemModel and MyListAdapter to your need, added the id and description properties):
List<MyItemModel> myListModel = new ArrayList<MyItemModel>();
try{
JSONArray entries = json.getJSONArray("entries");
for(int i=0;i<entries.length();i++){
MyItemModel item = new MyItemModel();
JSONObject e = entries.getJSONObject(i);
alKey.add(e.getInt("key"));
item.id = i;
item.title = e.getString("title");
item.description = e.getString("description");
// you can change the button action at this point:
// item.onClickListener = new OnClickListener(){...};
myListModel.add(item);
}
}catch(JSONException e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
ListAdapter adapter = new MyListAdapter(getLayoutInflater().inflate(R.layout.shelfrow, this));
adapter.setModel(myListModel);
setListAdapter(adapter);
lv = getListView();
lv.setTextFilterEnabled(true);
You can create your own class extending ArrayAdapter that will hold your list and set onClickListener to the Button in each row.
But in getView method of your ArrayAdapter you have to create a new view every time.
for example - row layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="110dp"
android:background="#FFF"
android:layout_width="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:background="#FFF"
android:orientation="vertical"
android:padding="2dp"
android:layout_height="110dp">
<TextView android:id="#+id/list_item_title"
android:background="#FFF"
android:layout_width="fill_parent"
android:layout_height="40dp"/>
<Button android:id="#+id/download_button"
android:gravity="center"
android:text="Download"
android:layout_height="35dp"/>
</LinearLayout>
</RelativeLayout>
and getView method in ArrayAdapter
private List<Map<String, String>> jsonMapList;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.list_item, null);
// here you set textview values (title and description)
// TextView title = (TextView) v.findViewById(R.id.list_item_title);
// title.setText('bla');
// and set OnClickListener
Button button = (Button) v.findViewById(R.id.download_button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
downloadFile(getUrl(position));
}
});
return v;
}
// method that downloads file
private void downloadFile(String url) {}
// get url from your list by index
private String getUrl(int index) {
return jsonMapList.get(index).get("url");
}
Usage of Map is unnecessary, you could use any object you prefer.
In activity class
CustomAdapter listAdapter = new CustomAdapter(this, android.R.layout.simple_list_item_single_choice, jsonMapList);
setListAdapter(listAdapter);

Android Spinner databind using array list

I have a array list like this:
private ArrayList<Locations> Artist_Result = new ArrayList<Location>();
This Location class has two properties: id and location.
I need to bind my ArrayList to a spinner. I have tried it this way:
Spinner s = (Spinner) findViewById(R.id.SpinnerSpcial);
ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item, Artist_Result);
s.setAdapter(adapter);
However, it shows the object's hexadecimal value. So I think I have to set display the text and value for that spinner controller.
The ArrayAdapter tries to display your Location-objects as strings (which causes the Hex-values), by calling the Object.toString()-method. It's default implementation returns:
[...] a string consisting of the name of the class of which the object
is an instance, the at-sign character `#', and the unsigned
hexadecimal representation of the hash code of the object.
To make the ArrayAdadpter show something actually useful in the item list, you can override the toString()-method to return something meaningful:
#Override
public String toString(){
return "Something meaningful here...";
}
Another way to do this is, to extend BaseAdapter and implement SpinnerAdapter to create your own Adapter, which knows that the elements in your ArrayList are objects and how to use the properties of those objects.
[Revised] Implementation Example
I was playing around a bit and I managed to get something to work:
public class Main extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create and display a Spinner:
Spinner s = new Spinner(this);
AbsListView.LayoutParams params = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT
);
this.setContentView(s, params);
// fill the ArrayList:
List<Guy> guys = new ArrayList<Guy>();
guys.add(new Guy("Lukas", 18));
guys.add(new Guy("Steve", 20));
guys.add(new Guy("Forest", 50));
MyAdapter adapter = new MyAdapter(guys);
// apply the Adapter:
s.setAdapter(adapter);
// onClickListener:
s.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
/**
* Called when a new item was selected (in the Spinner)
*/
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
Guy g = (Guy) parent.getItemAtPosition(pos);
Toast.makeText(
getApplicationContext(),
g.getName()+" is "+g.getAge()+" years old.",
Toast.LENGTH_LONG
).show();
}
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
});
}
/**
* This is your own Adapter implementation which displays
* the ArrayList of "Guy"-Objects.
*/
private class MyAdapter extends BaseAdapter implements SpinnerAdapter {
/**
* The internal data (the ArrayList with the Objects).
*/
private final List<Guy> data;
public MyAdapter(List<Guy> data){
this.data = data;
}
/**
* Returns the Size of the ArrayList
*/
#Override
public int getCount() {
return data.size();
}
/**
* Returns one Element of the ArrayList
* at the specified position.
*/
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int i) {
return i;
}
/**
* Returns the View that is shown when a element was
* selected.
*/
#Override
public View getView(int position, View recycle, ViewGroup parent) {
TextView text;
if (recycle != null){
// Re-use the recycled view here!
text = (TextView) recycle;
} else {
// No recycled view, inflate the "original" from the platform:
text = (TextView) getLayoutInflater().inflate(
android.R.layout.simple_dropdown_item_1line, parent, false
);
}
text.setTextColor(Color.BLACK);
text.setText(data.get(position).name);
return text;
}
}
/**
* A simple class which holds some information-fields
* about some Guys.
*/
private class Guy{
private final String name;
private final int age;
public Guy(String name, int age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
}
I fully commented the code, if you have any questions, don't hesitate to ask them.
Simplest Solution
After scouring different solutions on SO, I found the following to be the simplest and cleanest solution for populating a Spinner with custom Objects. Here's the full implementation:
Location.java
public class Location{
public int id;
public String location;
#Override
public String toString() {
return this.location; // What to display in the Spinner list.
}
}
res/layout/spinner.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="14sp"
android:textColor="#FFFFFF"
android:spinnerMode="dialog" />
res/layout/your_activity_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Spinner
android:id="#+id/location" />
</LinearLayout>
In Your Activity
// In this case, it's a List of Locations, but it can be a List of anything.
List<Location> locations = Location.all();
ArrayAdapter locationAdapter = new ArrayAdapter(this, R.layout.spinner, locations);
Spinner locationSpinner = (Spinner) findViewById(R.id.location);
locationSpinner.setAdapter(locationAdapter);
// And to get the actual Location object that was selected, you can do this.
Location location = (Location) ( (Spinner) findViewById(R.id.location) ).getSelectedItem();
Thanks to Lukas' answer above (below?) I was able to get started on this, but my problem was that his implementation of the getDropDownView made the dropdown items just a plain text - so no padding and no nice green radio button like you get when using the android.R.layout.simple_spinner_dropdown_item.
So as above, except the getDropDownView method would be:
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(android.R.layout.simple_spinner_dropdown_item, null);
}
TextView textView = (TextView) convertView.findViewById(android.R.id.text1);
textView.setText(items.get(position).getName());
return convertView;
}
Well, am not gonna confuse with more details.
Just create your ArrayList and bind your values like this.
ArrayList tExp = new ArrayList();
for(int i=1;i<=50;i++)
{
tExp.add(i);
}
Assuming that you have already a spinner control on your layout say with id, spinner1. Add this code below.
Spinner sp = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<String> adp1=new ArrayAdapter<String>this,android.R.layout.simple_list_item_1,tExp);
adp1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp.setAdapter(adp1);
All the above code goes under your onCreate function.
Thank Lukas, you help me a lot.
I d'like to improve your answer.
If you just want to access the selected item later, you can use this :
Spinner spn = (Spinner) this.findViewById(R.id.spinner);
Guy oGuy = (Guy) spn.getSelectedItem();
So you don't have to use the setOnItemSelectedListener() in your initialisation :)

Categories

Resources