I try to create a AutoCompleteTextView with custom list items, like showing a picture and a name in one list item. I know how to create it with 1 line of text in a list item but i'm a bit confused on who to do this with more views. I was thing about a ListAdapter and assigning the values to the right views. I'm pretty stuck here. I hope someone can give me a push in the right direction. Question is updated below.
Main activity:
public class AutocompleteCustomActivity extends Activity {
String[] firstView = {"Apple","Banana","Strawberry"};
String[] secondView = {"Green","Yellow","Red"};
AutoCompleteTextView autocomplete;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/*
// Simple 1 line list item
this.autocomplete = (AutoCompleteTextView) findViewById(R.id.autocomplete);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, firstView);
autocomplete.setAdapter(adapter);
*/
// 2 Lines of text in list item
this.autocomplete = (AutoCompleteTextView) findViewById(R.id.autocomplete);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.two_list_items, firstView);
autocomplete.setAdapter(adapter);
}
}
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" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
UPDATE:
After a lot of hardcore Googling and trial and erroring i came up with this code. I think it's pretty oké but the list items keep showing after selecting one. I know it's the settext that opens the new listitems.
I found this post: Disable Android AutoCompleteTextView after user selects item from drop down
But i don't know what he means :( Anyone knows how to fix this?
package com.sb.autocompletecustom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.SimpleAdapter;
public class AutocompleteCustomActivity extends Activity {
AutoCompleteTextView autocomplete;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Data to fill autocomplete
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Map<String, String> curGroupMap = new HashMap<String, String>();
list.add(curGroupMap);
curGroupMap.put("name", "Banana");
curGroupMap.put("color", "Yellow");
curGroupMap = new HashMap<String, String>();
list.add(curGroupMap);
curGroupMap.put("name", "Strawberry");
curGroupMap.put("color", "Red");
curGroupMap = new HashMap<String, String>();
list.add(curGroupMap);
curGroupMap.put("name", "Strawberry");
curGroupMap.put("color", "Black");
// 2 Lines of text in list item
this.autocomplete = (AutoCompleteTextView) findViewById(R.id.autocomplete);
SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.two_list_items, new String[] { "name", "color" }, new int[] { R.id.textView1, R.id.textView2 });
autocomplete.setAdapter(adapter);
autocomplete.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> p, View v, int pos, long id) {
Map<String, String> map = (Map<String, String>) p.getItemAtPosition(pos);
String itemName = map.get("name");
autocomplete.setText(itemName);
}
});
}
}
use a custom list adapter. you can inflate the layout and assign the values
public class AutoCompleteCursorAdapter extends CursorAdapter implements Filterable{
private TextView txtDrName, txtDrugName, txtDrugManufacturer;
private int rowResID;
private static Cursor c;
private String autoCompleteTextName;
Context context;
int layout;
public AutoCompleteCursorAdapter(Context context, int layout ) {
super(context, c);
// this.c = c;
this.context = context;
this.autoCompleteTextName = autoCompleteTextName;
this.layout = layout;
}
public long getItemId(int position) {
return position;
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(layout, parent, false);
txtDrName = (TextView)v.findViewById(R.id.txtAutoName) ;
....
}
return v;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
txtDrName = (TextView) view.findViewById(R.id.txtAutoName) ;
}
#Override
public String convertToString(Cursor cursor) {
// this method dictates what is shown when the user clicks each entry in your autocomplete list
String name="";
name = cursor.getString(cursor.getColumnIndex("prefix"))+" "+cursor.getString(cursor.getColumnIndex("firstName"));
}
return name;
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
// this is how you query for suggestions
if (getFilterQueryProvider() != null)
{ return getFilterQueryProvider().runQuery(constraint); }
if(constraint!=null){
DataBaseHelper db = new DataBaseHelper(context);
db.openDataBase();
if(autoCompleteTextName.equals(AppConstants.AUTOCOMPLETEDOCTORNAME)){
c = db.getStaffStartingWith((String) constraint);
}
else if (autoCompleteTextName.equals(AppConstants.AUTOCOMPLETEDRUGNAME)){
c = db.getDrugsForStartingWith((String) constraint);
}
c.moveToFirst();
db.close();
}
return c;
}
`
Related
In my program I have fetched the data's from the server and view it in a listview. Then from those retrieved data in listview I have to select a string and that string will be passed on to another activity. My data's are retrieved and showed in listview but when I select an item(String) and try to send it to the next activity then instead of that string the package name is passed.
The layout code for retrieving and sending selected String is given below:
public class Doctors_layout extends Fragment implements
AdapterView.OnItemSelectedListener{
public final static String Message = "Sohan";
View myView;
Spinner spinner;
String selectedCity;
Context myContext;
String jsonResult;
JSONObject jsonObject;
JSONArray jsonArray;
String JSON_String;
ContactAdapter contactAdapter;
ListView listView;
Button button;
String send;
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.doctors_directory, container, false);
myContext = inflater.getContext();
contactAdapter = new ContactAdapter(myContext, R.layout.row_layout);
spinner = (Spinner)myView.findViewById(R.id.spinner);
listView = (ListView)myView.findViewById(R.id.listView);
listView.setAdapter(contactAdapter);
spinner.setOnItemSelectedListener(this);
List<String> city = new ArrayList<String>();
city.add("Choose a City");
city.add("Chittagong");
city.add("Dhaka");
ArrayAdapter<String> aAdapter = new ArrayAdapter<String>(myContext, android.R.layout.simple_spinner_item ,city);
aAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(aAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// here we have to select medical name and intent viewDoctor page
Intent intent = new Intent(myContext, viewDoctor.class);
send = listView.getItemAtPosition(position).toString(); // doesn't retrieve the selected text, intead chooses package name
intent.putExtra(Message, send);
Toast.makeText(myContext, "Listview item "+send, Toast.LENGTH_SHORT).show();
startActivity(intent);
}
});
return myView;
}
And my custom contact adapter class is given below:
package com.example.sohan.patient;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Sohan on 6/9/2016.
*/
public class ContactAdapter extends ArrayAdapter {
List list = new ArrayList();
View row;
ContactHolder contactHolder;
public ContactAdapter(Context context, int resource) {
super(context, resource);
}
public void add(List<Contacts> updatedList) {
list.clear();
list.addAll(updatedList);
notifyDataSetChanged();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public int getCount() {
return list.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
row = convertView;
if(row==null){
LayoutInflater layoutInflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.row_layout,parent,false);
contactHolder = new ContactHolder();
contactHolder.MedicalName =(TextView) row.findViewById(R.id.textView5);
row.setTag(contactHolder);
}
else{
contactHolder = (ContactHolder)row.getTag();
}
Contacts contacts = (Contacts)this.getItem(position);
contactHolder.MedicalName.setText(contacts.getMedicalName());
return row;
}
static class ContactHolder{
TextView MedicalName;
}
}
Try this, I hope it work...
send = ((TextView) view.findViewById(R.id.textView5)).getText().toString();
or
send = (String) parent.getItemAtPosition(position);
thanks..
send = listView.getItemAtPosition(position).toString();
you are sending a listView object and not actual string.
use:
send = yourListOfStrings.get(position)
UDP:
You are trying to create an adapter with onItemClick listener attacked to it:
contactAdapter = new ContactAdapter(myContext, R.layout.row_layout);
spinner = (Spinner)myView.findViewById(R.id.spinner);
listView = (ListView)myView.findViewById(R.id.listView);
listView.setAdapter(contactAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
right?
So you are suppose to fill(But I haven't found where you are doing this) this adapter with some data:
public void add(List<Contacts> updatedList) {
list.clear();
list.addAll(updatedList);
notifyDataSetChanged();
}
and you want to send a string from from the element of this list to another acitvity, right?
So you need to select an element of this list
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
send = updatedList.get(position).getYourString
inside onItemClickListener
while i am searching for examples to make list of answers in expandable list i found code which use 4 java classes and one xml with expand list but not use xml for parent and child and i want to change text color and check box color
XML
<Spinner
android:id="#+id/coursescomplaint"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:layout_gravity="center"
android:spinnerMode="dialog"
style="#style/spinner_style"/>
<ExpandableListView
android:id="#+id/expandcomplaintcourse"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#color/Button"
android:text="Submit"
android:layout_gravity="center"/>
JAVA
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ExpandableListView;
import android.widget.Spinner;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Complaint extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private static List<Answers> questions;
private ExpandableListView expandableListView;
private AnswersAdabter adapter;
private int lastExpandedPosition = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_complaint);
LoadQuestions();
expandableListView = (ExpandableListView)findViewById(R.id.expandcomplaintcourse);
adapter = new AnswersAdabter(this, questions);
expandableListView.setAdapter(adapter);
// The choice mode has been moved from list view to adapter in order
// to not extend the class ExpansibleListView
adapter.setChoiceMode(AnswersAdabter.CHOICE_MODE_SINGLE_PER_GROUP);
// Handle the click when the user clicks an any child
expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
adapter.setClicked(groupPosition, childPosition);
return false;
}
});
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
if (lastExpandedPosition != -1 && groupPosition != lastExpandedPosition) {
expandableListView.collapseGroup(lastExpandedPosition);
}
lastExpandedPosition = groupPosition;
}
});
// Spinner element
Spinner spinner = (Spinner) findViewById(R.id.coursescomplaint);
// Spinner click listener
spinner.setOnItemSelectedListener(this);
// Spinner Drop down elements
List<String> categories = new ArrayList<String>();
categories.add("Course1");
categories.add("Course2");
categories.add("Course3");
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, R.layout.spinner, categories);
// Drop down layout style - list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinner.setAdapter(dataAdapter);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// On selecting a spinner item
String item = parent.getItemAtPosition(position).toString();
// Showing selected spinner item
Toast.makeText(parent.getContext(), "Selected: " + item, Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
private void LoadQuestions() {
questions = new ArrayList<Answers>();
ArrayList<String> citiesAustralia = new ArrayList<String>(
Arrays.asList("Brisbane", "Hobart", "Melbourne", "Sydney"));
questions.add(new Answers("Australia", citiesAustralia));
ArrayList<String> citiesChina = new ArrayList<String>(
Arrays.asList("Beijing", "Chuzhou", "Dongguan", "Shangzhou"));
questions.add(new Answers("China", citiesChina));
ArrayList<String> citiesIndia = new ArrayList<String>(
Arrays.asList("Bombay", "Calcutta", "Delhi", "Madras"));
questions.add(new Answers("India", citiesIndia));
ArrayList<String> citiesNewZealand = new ArrayList<String>(
Arrays.asList("Auckland", "Christchurch", "Wellington"));
questions.add(new Answers("New Zealand", citiesNewZealand));
ArrayList<String> citiesRussia = new ArrayList<String>(
Arrays.asList("Moscow", "Kursk", "Novosibirsk", "Saint Petersburg"));
questions.add(new Answers("Russia", citiesRussia));
}
}
I try to show something into listview using arraylist and simple adapter.
I tried something like below but in my result shows the last names of the arraylist.
What is my wrong i cant understand.
final ListView listView = (ListView) findViewById(R.id.mylist);
ArrayList<HashMap<String, String>> list_of_bookmarks = new ArrayList<HashMap<String, String>>();
HashMap<String, String> b = new HashMap<String, String>();
String[] from = { "php_key","c_key","android_key","hacking_key" };
String[] name_of_bookmarks = { "php","c","android","hacking" };
for(int i=0;i<4;i++)
{
b.put(from[i],name_of_bookmarks[i]);
list_of_bookmarks.add(b);
}
};
int[] to = { R.id.txt1,R.id.txt1,R.id.txt1,R.id.txt1};
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), list_of_bookmarks, R.layout.list_layout, from, to);
listView.setAdapter(adapter);
I just want to show "php","c","android","hacking" in a listview.
And what should be more efficient way to do that.I am a beginner so you may suggest a better way which should i follow
My advice to you would be to create a separate class that extends the Adapter(or some subclass of it)
Here is a simple example of a String array adapter.
package ro.gebs.captoom.adapters;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import antistatic.spinnerwheel.adapters.AbstractWheelTextAdapter;
import com.example.captoom.R;
public class LanguagesAdapter extends AbstractWheelTextAdapter {
// Countries names
private String languages[];
public LanguagesAdapter(Context context) {
super(context, R.layout.lang_item, NO_RESOURCE);
languages = context.getResources().getStringArray(R.array.lang_array);
setItemTextResource(R.id.language_txt);
}
#Override
public View getItem(int index, View cachedView, ViewGroup parent) {
View view = super.getItem(index, cachedView, parent);
return view;
}
#Override
public int getItemsCount() {
return languages.length;
}
#Override
protected CharSequence getItemText(int index) {
return languages[index];
}
}
and the usage is simple just use the method .setAdapter();
Or another example which uses an arrayAdapter:
package apc.example;
import java.util.ArrayList;
import utils.BitmapManager;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class PersonAdapter extends ArrayAdapter<Person> {
Context context;
int layoutResourceId;
ArrayList<Person> data = null;
public PersonAdapter(Context context, int layoutResourceId,
ArrayList<Person> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ItemHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ItemHolder();
holder.imgIcon = (ImageView) row.findViewById(R.id.icon);
holder.txtName = (TextView) row.findViewById(R.id.title);
holder.txtDescription = (TextView) row.findViewById(R.id.desc);
row.setTag(holder);
} else {
holder = (ItemHolder) row.getTag();
}
Person bean = data.get(position);
holder.txtName.setText(bean.getName());
holder.txtDescription.setText(bean.getDescription());
Bitmap b = BitmapFactory.decodeResource(context.getResources(), R.drawable.user);
BitmapManager.INSTANCE.setPlaceholder(b);
BitmapManager.INSTANCE.loadBitmap(bean.getUrl(), holder.imgIcon, 80, 80);
return row;
}
public static class ItemHolder {
public ImageView imgIcon;
TextView txtName;
TextView txtDescription;
}
public void updateAdapter(ArrayList<Person> pers){
this.data = pers;
}
}
This is an example of an adapter for a more complex class that has more fields rather than a simple string. But that can easily be modified to ArrayAdapter<String> and then go from there.
Anyways i think it's always a best practice to write your custom adapters for listviews.
Hope this helps!
Main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="60dp" >
<ListView
android:id="#+id/zone_list"
android:layout_marginBottom="70dp"
android:background="#drawable/batteryborder"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
setlanguage.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="60dp">
<TextView
android:id="#+id/tvName"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="18dp"
android:gravity="center_vertical" />
</LinearLayout>
add in onCreate() of your activity file
ListView listView;
String[] from = { "php_key","c_key","android_key","hacking_key" };
ArrayAdapter arrayAdapter;
listView = (ListView) findViewById(R.id.zone_list);
arrayAdapter = new ArrayAdapter<>(this,R.layout.setlanguage, R.id.tvName, from);
listView.setAdapter(arrayAdapter);
You're reusing the same view in your int[] object.
int[] to = { R.id.txt1,R.id.txt1,R.id.txt1,R.id.txt1};
It looks like it's treating them all as the same object, so each time it adds a new item it changes the previous ones.
In order to use the SimpleAdapter you will need to define each view in the XML with different IDs.
int[] to = { R.id.txt1,R.id.txt2,R.id.txt3,R.id.txt4};
The SimpleAdapter may be simpler in regard to it's internal complexity, but it's definitely not simpler to actually use. With an ArrayAdapter you can just pass it the list of items and let it generate views automatically. It can be any size you need it to be so long as you don't run out of memory. (See below for example)
Once you start working with custom adapters I highly recommend you watch Romain Guy & Adam Powell's I/O talk. It's all a lot to take in when learning, but they do a great job of explaining how ListViews work.
//List of Items
String[] name_of_bookmarks = { "php","c","android","hacking" };
//Create your List object for the ArrayAdapter
//and make it the same size as name_of_books
List<String> listBookmarks = new ArrayList<String>(Array.getLength(name_of_bookmarks));
//Add name_of_bookmarks contents to listBookmarks
Collections.addAll(listBookmarks, name_of_books);
//Create an ArrayAdapter passing it the Context, a generic list item and your list
//An alternative to "this" would be "getApplicationContext()" from your main activity
//or "getActivity()" from a fragment. "getBaseContext()" is not recommended.
ArrayAdapter arrayAdapter = new ArrayAdapter(this, R.layout.list_item_text, listBookmarks);
//Set the adapter to your ListView
final ListView listView = (ListView) findViewById(R.id.mylist);
listView.setAdapter(arrayAdapter);
Try this one
public class MyFragment extends ListFragment{
String[] from = { "php_key","c_key","android_key","hacking_key" };
String[] name_of_bookmarks = { "php","c","android","hacking" };
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
List<HashMap<String, String>> list= new ArrayList<HashMap<String,String>>();
for (int i = 0; i < name_of_bookmarks.length; i++) {
HashMap<String, String> map= new HashMap<String, String>();
map.put("key", name_of_bookmarks[i]);
list.add(map);
}
String[] from = { "key" };
int[] to = { R.id.txt};
SimpleAdapter adapter = new SimpleAdapter(getActivity().getBaseContext(), list, R.layout.list_layout, from, to);
setListAdapter(adapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
}
Whatever You Are Face Problem Exactly I Am Face Of The Problem Called "List
View Display Last Position Of Data Of An Array..."
The Problem Is Generated With Hash Map
final ListView listView = (ListView) findViewById(R.id.mylist);
ArrayList<HashMap<String, String>> list_of_bookmarks = new ArrayList<HashMap<String, String>>();
String[] from = { "php_key","c_key","android_key","hacking_key" };
String[] name_of_bookmarks = { "php","c","android","hacking" };
for(int i=0;i<4;i++)
{
HashMap<String, String> b = new HashMap<String, String>();
b.put(from[i],name_of_bookmarks[i]);
list_of_bookmarks.add(b);
}
};
int[] to = { R.id.txt1,R.id.txt1,R.id.txt1,R.id.txt1};
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), list_of_bookmarks, R.layout.list_layout, from, to);
listView.setAdapter(adapter);
Try Out This One If Any Doubt Created In Your Mind Then Ask Me Whatever Question Again
Simply You Have To Declared Your Hash Map Inside Your For Loop ...
Using Hash Map Inside Your For Loop Variable 'b' Created Each & Every Time With Considered As An Different Object. And Then Simply Array List Display Different Object Of Hash Map.
You Are Using Same Object To Store Value Of Hash Map And That Variable Was Override With Same Name That's Why you Are Faced The Problem
Thank You...
I have a Listview which pulls and displays data from a sqlite DB. Data in the first column of the DB is displayed in the ListView and when clicked, an Activity starts showing the rest of the column associated with the first column. When the data is edited the ListView needs to be updated to reflect this, but it doesn't show the updates unless the application is restarted.
I've tried calling, notifyDataSetChanged() and startActivityForResult() in my onResume() method but that didn't work. What method should I use to accomplish updating the ListView in my current code?
I understand a SimpleCursorAdapter may be used and I have tried to implement that code with no success. I'm a novice and need actual code to understand what needs to be done.
public class LoginList extends Activity implements OnClickListener, OnItemClickListener {
private ListView loginList;
private Button webLogin;
private ListAdapter loginListAdapter;
private ArrayList<LoginDetails> loginArrayList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_listview);
loginList = (ListView)
findViewById(R.id.loginlist);
loginList.setOnItemClickListener(this);
webLogin = (Button)
findViewById(R.id.button3);
webLogin.setOnClickListener(this);
loginArrayList = new ArrayList<LoginDetails>();
loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList());
loginList.setAdapter(loginListAdapter);
}
#Override
public void onClick (View v) {
Intent webLoginIntent = new Intent (this, LoginPlusActivity.class);
startActivity(webLoginIntent);
}
public List<String> populateList () {
List<String> webNameList = new ArrayList<String>();
dataStore openHelperClass = new dataStore (this);
SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase();
Cursor cursor = sqliteDatabase.query(dataStore.TABLE_NAME_INFOTABLE, null, null, null, null, null, dataStore.COLUMN_NAME_SITE, null);
startManagingCursor(cursor);
while (cursor.moveToNext()) {
String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE));
String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS));
String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME));
String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD));
String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES));
LoginDetails lpDetails = new LoginDetails();
lpDetails.setsName(sName);
lpDetails.setwUrl(wUrl);
lpDetails.setuName(uName);
lpDetails.setpWord(pWord);
lpDetails.setlNotes(lNotes);
loginArrayList.add(lpDetails);
webNameList.add(sName);
}
sqliteDatabase.close();
return webNameList;
}
#Override
protected void onResume() {
super.onResume();
loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList());
loginList.setAdapter(loginListAdapter);
}
#Override
public void onItemClick(AdapterView<?> arg0 , View arg1, int arg2, long arg3) {
Toast.makeText(getApplicationContext(), "Selected ID :" + arg2, Toast.LENGTH_SHORT).show();
Intent updateDeleteLoginInfo = new Intent (this, UpdateDeleteLoginList.class);
LoginDetails clickedObject = loginArrayList.get(arg2);
Bundle loginBundle = new Bundle();
loginBundle.putString("clickedWebSite",clickedObject.getsName());
loginBundle.putString("clickedWebAddress",clickedObject.getwUrl());
loginBundle.putString("clickedUserName",clickedObject.getuName());
loginBundle.putString("clickedPassWord",clickedObject.getpWord());
loginBundle.putString("clickedNotes",clickedObject.getlNotes());
updateDeleteLoginInfo.putExtras(loginBundle);
startActivityForResult(updateDeleteLoginInfo, 0);
}
}
This is exactly what a Loader is great for. I suggest you create a SimpleCursorAdapter to bind the DB to the UI (ListView in this case), a ContentProvider to interface with the DB, and a CursorLoader to monitor the DB for changes, and update the UI when necessary. The Loader will handle all DB changes and update your ListView by simply updating your adapter. It seems like a lot of work up front, but is incredibly powerful once configured, and will work through the entire Android lifecycle.
These tutorials should be helpful:
https://developer.android.com/training/load-data-background/index.html
http://www.vogella.com/articles/AndroidSQLite/article.html#background_loader
https://github.com/browep/AndroidCursorLoaderTutorial
Edit
private ArrayList<LoginDetails> loginArrayList = new ArrayList<LoginDetails>();;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_listview);
loginList = (ListView)
findViewById(R.id.loginlist);
loginList.setOnItemClickListener(this);
webLogin = (Button)
findViewById(R.id.button3);
webLogin.setOnClickListener(this);
loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,loginArrayList );
loginList.setAdapter(loginListAdapter);
populateList();
}
#Override
public void onClick (View v) {
Intent webLoginIntent = new Intent (this, LoginPlusActivity.class);
startActivity(webLoginIntent);
}
public void populateList () {
loginListAdapter.clear();
loginArrayList.clear();
dataStore openHelperClass = new dataStore (this);
SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase();
Cursor cursor = sqliteDatabase.query(dataStore.TABLE_NAME_INFOTABLE, null, null, null, null, null, dataStore.COLUMN_NAME_SITE, null);
startManagingCursor(cursor);
while (cursor.moveToNext()) {
String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE));
String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS));
String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME));
String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD));
String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES));
LoginDetails lpDetails = new LoginDetails();
lpDetails.setsName(sName);
lpDetails.setwUrl(wUrl);
lpDetails.setuName(uName);
lpDetails.setpWord(pWord);
lpDetails.setlNotes(lNotes);
loginArrayList.add(lpDetails);
webNameList.add(sName);
}
loginListAdapter.notifyDatasetChanged();
sqliteDatabase.close();
}
You are losing reference to your listview that why your list isn't updating...
Do this modification in your code.
1. Initialize your ArrayList when it is declared(globally).
ArrayList loginArrayList = new ArrayList<LoginDetails>();
Directly set assign list to Adapter (onCreate)
loginListAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, loginArrayList);
call populateList() in onCreate().
In your populateList() instead of Adding data to the new list add to existing list associated with your Adapter i.e loginArrayList
if your list is completely new call adapter.clear() and loginArrayList.clear() in the populateList() before adding data to the loginArrayList.
After Adding the data to the loginArrayList call adapter.notifyDataSetChanged()
This should Work...
My recomendation.
Do not do a loop to load your list. If it is a simple list with all
strings. Try to use a SimpleCursorAdapter and will make your app
faster and shorter code.
Once you update the database, then what you do is query the DB to get the Cursor, and to the Adapter use .swapCursor(newCursor). That will update your list while maintaining the scroll position.
If you're manually creating the backing data of the adapter (in this case you're using an ArrayAdapter - which is completely acceptable in a lot of cases) then when the database changes you need to requery the database, recreate your dataset, change the backing dataset of your adapter, and tell the list that the dataset has changed.
A way to accomplish this may be to broadcast an intent that lets your activity know to perform the steps mentioned above (by catching that intent with a BroadcastReceiver).
Here's my sample code for editing the each row as well as the database of the listview I hope it will helps you
First create I create an Adapter name "ListAdapterItem.java"
import java.util.ArrayList;
import java.util.HashMap;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class ListAdapterItem extends BaseAdapter {
private ArrayList<HashMap<String, Object>> list;
private Context context;
private RelativeLayout ll;
// used to keep selected position in ListView
private int selectedPos = -1; // init value for not-selected
private TextView label,label_id;
String name,id;
public ListAdapterItem (Context context,ArrayList<HashMap<String, Object>> list) {
this.list = list;
this.context = context;
}
public void setSelectedPosition(int pos) {
selectedPos = pos;
// inform the view of this change
notifyDataSetChanged();
}
public int getSelectedPosition() {
return selectedPos;
}
public View getView(int position, View convertView, ViewGroup parent) {
ll = (RelativeLayout) LayoutInflater.from(this.context).inflate(R.layout.data_list_item, null);
// get text view
label = (TextView) ll.findViewById(R.id.txtview_country_name);
label_id=(TextView) ll.findViewById(R.id.txtview_id);
id=list.get(position).get("Id").toString();
name = list.get(position).get("Name").toString();
label.setText(name);
label_id.setText(id);
return ll;
}
public int getCount() {
return this.list.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
}
And here's my data_list_item
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="#+id/txtview_id"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_margin="8dp"
android:layout_marginRight="2dp"
android:textColor="#android:color/black"
android:textSize="22dp"
android:visibility="invisible"/>
<TextView
android:id="#+id/txtview_country_name"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_margin="8dp"
android:layout_marginRight="2dp"
android:textColor="#android:color/black"
android:textSize="22dp" />
</RelativeLayout>
And the main Class "Main.java"
public class Main extends Activity implements OnClickListener {
String name;
SQLiteDatabase db;
Cursor cursor;
private ProgressDialog progressDialog;
public ListAdapterItem list_adapter;
private ArrayList<HashMap<String, Object>> lst_data;
private HashMap<String, Object> hm;
private ListView listview;
private String list_id;
private int counter_id,selectedPosition;
private View selectedView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
lst_data = new ArrayList<HashMap<String, Object>>();
listview = (ListView) findViewById(R.id.list);
new FetchDB().execute();
}
private class FetchDB extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> {
protected void onPreExecute() {
progressDialog = ProgressDialog.show(Main.this,"Fetching Data", "Loading,Please wait...", true);
}
protected ArrayList<HashMap<String, Object>> doInBackground(String... lstStrings)throws IllegalArgumentException {
try {
db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
cursor = db.rawQuery("SELECT * FROM person WHERE Id <> ''",null);
if (cursor != null && cursor.getCount() > 0) {
if (cursor.moveToFirst()) {
do {
hm = new HashMap<String, Object>();
hm.put("Id",cursor.getInt(cursor.getColumnIndex("Id")));
hm.put("Name", cursor.getString(cursor.getColumnIndex("Name")));
lst_data.add(hm);
} while (cursor.moveToNext());
}// end of cursor.moveToFirst()
cursor.close();
}
} catch (Exception e) {
e.getMessage();
}
db.close();// database close
return lst_data;
}// end of doInbackgournd
#Override
protected void onPostExecute(ArrayList<HashMap<String, Object>> result) {
progressDialog.dismiss();
list_adapter = new ListAdapterItem(Main.this,result);
listview.setAdapter(list_adapter);
listview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
list_adapter.setSelectedPosition(arg2);
selectedPosition = arg2;
selectedView = arg1;
list_id=((TextView) selectedView.findViewById(R.id.txtview_id)).getText().toString();
}
});
}
}// end of FetchDBTask
private class SaveTask extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> {
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(Main.this,"Saving Data", "Loading,Please wait...", true);
}
protected ArrayList<HashMap<String, Object>> doInBackground(String... arg0)throws IllegalArgumentException {
counter_id++;
name = editext_name.getText().toString();
hm = new HashMap<String, Object>();
hm.put("Id",counter_id);
hm.put("Name",name);
lst_data.add(hm);
saveDB();
return lst_data;
}// end of doInbackgournd
protected void onPostExecute(ArrayList<HashMap<String, Object>> result) {
progressDialog.dismiss();
list_adapter = new ListAdapterItem(Main.this,result);
listview.setAdapter(list_adapter);
listview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
list_adapter.setSelectedPosition(arg2);
selectedPosition = arg2;
selectedView = arg1;
list_id=((TextView) selectedView.findViewById(R.id.txtview_id)).getText().toString();
}
});
}
}// end of saveTask
public void saveDB(){
String sql;
db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
// create table if not e exist
db.execSQL("CREATE TABLE IF NOT EXISTS person(Name VARCHAR ,Id INT(3));");
sql = "SELECT * FROM person WHERE Id="+list_id; //selected or click row in list item
Cursor cursor = db.rawQuery(sql, null);
if (cursor.moveToFirst()) {
String sqlUpdate = "UPDATE person SET Name=? WHERE Id="+db_id;
db.execSQL(sqlUpdate, new Object[] {db_name});
cursor.close();
db.close();// database close
} else {// empty insert
String sqlInsert = "INSERT INTO person VALUES (?,"+null+")";
db.execSQL(sqlInsert, new Object[] {db_name,db_address,db_phone,db_email,db_license,db_comments,db_company,db_policy,db_phone_insurance,vehc_year,vehc_make,vehc_model,vehc_license,vehc_vinnum,vehc_color,db_position });
cursor.close();
db.close();// database close
}
}
//Edit by row
private class EditData extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> {
protected void onPreExecute() {
progressDialog = ProgressDialog.show(Main.this,"Saving Data", "Loading Please wait...", true);
}
protected ArrayList<HashMap<String, Object>> doInBackground(String... id)throws IllegalArgumentException {
name = editext_name.getText().toString();
hm = new HashMap<String, Object>();
hm.put("Id",counter_id);
hm.put("Name",name);
lst_data.set(selectedPosition, hm); //specific row update
list_id=Integer.parseInt(edit_counter);
saveDB();
return lst_data;
}// end of doInbackgournd
protected void onPostExecute(ArrayList<HashMap<String, Object>> result) {
progressDialog.dismiss();
list_adapter = new ListAdapterItem(Main.this,result);
listview.setAdapter(list_adapter);
}
}
}
And the main_layout.xml
<?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="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="#android:color/transparent"
android:cacheColorHint="#00000000"
android:dividerHeight="2dp"
android:paddingTop="8dp"
android:transcriptMode="normal" />
</LinearLayout>
Specify your id every listrow in the listview hope that this answer your question
I think that in your populate() method before the while block you should call loginListAdapter.notifyDataSetChanged() and loginListAdapter.clear();
That would clear the adapter and notice to it of the new list of data.
The block will look like this:
loginListAdapter.notifyDataSetChanged();
loginListAdapter.clear();
while (cursor.moveToNext()) {
String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE));
String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS));
String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME));
String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD));
String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES));
LoginDetails lpDetails = new LoginDetails();
lpDetails.setsName(sName);
lpDetails.setwUrl(wUrl);
lpDetails.setuName(uName);
lpDetails.setpWord(pWord);
lpDetails.setlNotes(lNotes);
loginArrayList.add(lpDetails);
webNameList.add(sName);
}
I Just edited because the order you call the notify and clear wasn't correct. The clear must occur after the notify, is just what i got from my experience, unless the adapter wouldn't redraw the list.
Try this code
in public area add variable : List<String> arrayList = new ArrayList<String>();
and in onCreate() add this :
arrayList = populateList();
//then add variable in adapter like this
loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrayList );
in onResume() this code:
#Override
protected void onResume() {
super.onResume();
loginArrayList.clear();
arrayList.clear();
arrayList = populateList();
loginListAdapter.notifyDataSetChanged()
}
Let us know if you solved it.
I currently have a listview which contains a couple of strings. These are called from a string array in strings.xml
<string name="app_name">Taxi Me</string>
<string-array name="taxi_array">
<item>Barrys Taxi</item>
<item>Boom Taxi</item>
</string-array>
What I was trying to do is create subitems for these so that i can show fields such as address and contact details etc. I made a customlistview a while back but cant work out how I can do it using the strings.xml file? Are there any particular tags I need to use so they show up in the list view?
Main Activity Code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String[] taxi = getResources().getStringArray(R.array.taxi_array);
final String[] address = getResources().getStringArray(R.array.taxi_add);
setListAdapter(new ArrayAdapter<String>(this, R.layout.listtaxi, taxi));
final ListView lv = getListView();
lv.setTextFilterEnabled(true);
for (int i = 0; i < taxi.length; i++) {
lv.add(new ListTaxi (taxi[i], address[i]));
}
/*lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
Toast.LENGTH_LONG).show();
}
});
*/
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, final int position, long id)
{
final int selectedPosition = position;
AlertDialog.Builder adb=new AlertDialog.Builder(ListTaxi.this);
adb.setTitle("Taxi Booking");
adb.setMessage("You Have Selected: "+lv.getItemAtPosition(position));
adb.setPositiveButton("Book", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(getApplicationContext(), Booking.class);
intent.putExtra("booking", taxi[selectedPosition]);
startActivity(intent);
}
});
adb.setNegativeButton("Cancel", null);
adb.show();
}
});
EDIT: Okay, just for kicks, I threw this together. It compiles and functions correctly, see if you can adapt it for your particular needs:
layout/taxi_list_item.xml
<?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="100dp"
android:padding="10dp"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/taxi_name"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/taxi_address"
/>
</LinearLayout>
layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
TaxiMain.java
package com.test.taxi;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class TaxiMain extends ListActivity {
/** Called when the activity is first created.
* #return */
class Taxi {
private String taxiName;
private String taxiAddress;
public String getName() {
return taxiName;
}
public void setName(String name) {
taxiName = name;
}
public String getAddress() {
return taxiAddress;
}
public void setAddress(String address) {
taxiAddress = address;
}
public Taxi(String name, String address) {
taxiName = name;
taxiAddress = address;
}
}
public class TaxiAdapter extends ArrayAdapter<Taxi> {
private ArrayList<Taxi> items;
private TaxiViewHolder taxiHolder;
private class TaxiViewHolder {
TextView name;
TextView address;
}
public TaxiAdapter(Context context, int tvResId, ArrayList<Taxi> items) {
super(context, tvResId, items);
this.items = items;
}
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.feed_view, null);
taxiHolder = new TaxiViewHolder();
taxiHolder.name = (TextView)v.findViewById(R.id.taxi_name);
taxiHolder.address = (TextView)v.findViewById(R.id.taxi_address);
v.setTag(taxiHolder);
} else taxiHolder = (TaxiViewHolder)v.getTag();
Taxi taxi = items.get(pos);
if (taxi != null) {
taxiHolder.name.setText(taxi.getName());
taxiHolder.address.setText(taxi.getAddress());
}
return v;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] taxiNames = getResources().getStringArray(R.array.taxi_name_array);
String[] taxiAddresses = getResources().getStringArray(R.array.taxi_address_array);
ArrayList<Taxi> taxiList = new ArrayList<Taxi>();
for (int i = 0; i < taxiNames.length; i++) {
taxiList.add(new Taxi(taxiNames[i], taxiAddresses[i]));
}
setListAdapter(new TaxiAdapter(this, R.layout.taxi_list_item, taxiList));
}
}
_____END EDIT_______
You'd probably be better off using a database for something like this, to keep the records tied together. If you're set on using arrays, one thing you could do is make a separate array for each item you need (e.g. taxi_array, taxi_address_array, taxi_phone_array) then make a Taxi object in your code:
class Taxi {
String taxiName;
String taxiAddress;
String taxiPhone;
public Taxi(String name, String address, String phone) {
taxiName = name;
taxiAddress = address;
taxiPhone = phone;
}
}
private List<Taxi> taxiList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] taxiNames = getResources().getStringArray("taxi_array");
String[] taxiAddresses = getResources().getStringArray("taxi_address_array");
String[] taxiPhones = getResources().getStringArray("taxi_phone_array");
taxiList = new ArrayList<Taxi>();
for (int i = 0; i < taxiNames.length; i++) {
taxiList.add(new Taxi(taxiNames[i], taxiAddresses[i], taxiPhones[i]));
}
}
(This is uncompiled code, some tweaks may be needed) But then you'll have a List of Taxi items, containing all of the compiled information from the different arrays. A database would still be a much better option (or even a CSV file with the data, in your assets).
I had same problem and I solved myself like this:
you can simply add subitem like this code and you don't need so much coding!!
<string name="app_name">Taxi Me</string>
<string-array name="taxi_array">
<item>
<item>Barrys Taxi</item>
<item>adress</item>
<item>contact</item>
<item>ANY THING...</item>
</item>
<item>
<item>Boom Taxi</item>
<item>adress</item>
<item>contact</item>
<item>ANY THING...</item>
</item>
</string-array>
Are you looking for some sort of nested Lists?
Have a look at ExpandableListView:
http://developer.android.com/reference/android/widget/ExpandableListView.html
and
http://mylifewithandroid.blogspot.com/2008/05/expandable-lists.html