Android Adapters, An Introduction
Android Adapters, An Introduction
Android
Adapters: an introduction
An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set. An AdapterView is a view whose children are determined by an Adapter. Some examples of AdapterViews are ListView, GridView, Spinner and Gallery.
ListAdapter: Extended Adapter that is the bridge between a ListView and the data that backs the
list. Frequently that data comes from a Cursor, but that is not required. The ListView can display any data provided that it is wrapped in a ListAdapter.
Introduction
In most mobile applications, we find a frequent usage of lists. A list is not often as simple as an array of strings, of integer... Furthermore, the data could be taken or stored in a remote machine. In any case, well be taking a look at what it takes to begin with a simple ListActivity.
The HowTo
First of all, if you've already taken a look at the first tutorial "HelloWorld", you might know how to create a new Android project on eclipse. So, to begin, you have to create a new Android Project (1.1 or newer) and
A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
name the activity MyListActivity (or whatever you prefer.). Next, modify your activity "MyListActivity" to extend the Android class ListActivity and adjust your code to look like the following:
package com.wikinut.android; import android.app.ListActivity; import android.os.Bundle; import android.widget.ListAdapter; public class MainListView extends ListActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); ListAdapter adapter = createAdapter(); setListAdapter(adapter); } /** * Creates and returns a list adapter for the current list activity * @return */ protected ListAdapter createAdapter() { return null; } }
Sounds good, isn't it?. We have a method to create our list adapter. Lets see then what we mean by adapters. Adapters group a collection of objects to an activity. In our case, we will create a simple list of strings (which in fact, is already provided by Android: ArrayAdapter) Bring some chages on your createAdapter() method to be like this:
/** * Creates and returns a list adapter for the current list activity * @return */ protected ListAdapter createAdapter() { // Create some mock data String[] testValues = new String[] { "Test1", "Test2", "Test3" }; // Create a simple array adapter (of type string) with the test values ListAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, testValues);
return adapter; }
The Context is simply the source of data in the list. In our application its simple, but sometimes it can be harder and more complex. The Layout is where the data will be rendered (and how it will look.) Were using a built-in Android layout for our needs (simple_list_item_1). The Data is what will be rendered, and is a simple list of strings. Final code should be like this:
package com.wikinut.android; import import import import android.app.ListActivity; android.os.Bundle; android.widget.ArrayAdapter; android.widget.ListAdapter;
public class MainListView extends ListActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); ListAdapter adapter = createAdapter(); setListAdapter(adapter); } /** * Creates and returns a list adapter for the current list activity * @return */ protected ListAdapter createAdapter() { // Create some mock data String[] testValues = new String[] { "Test1", "Test2", "Test3" }; // Create a simple array adapter (of type string) with the test values ListAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, testValues); return adapter; } }
06 07 08 09 10 11 12 13 14 15 16 }
} public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; }
2. Create the layout for the activity that display the list. This will be the layout for displaying the activity class. You can put this in res/layout folder
01 <?xml version="1.0" encoding="utf-8"?> 02 <LinearLayout 03 04 05 06 07 08 09 10 11 12 13 xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/white" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/dark_blue"
14 15 16 17 18 19 20 21 22 23 24 25 26 27
> <TextView android:id="@+id/list_header_title" android:text="@string/create_test_activity_title" style="@style/listSeparatorTextViewStyle" /> </LinearLayout> <ListView android:id="@android:id/list" android:layout_height="0dip" android:layout_width="fill_parent" android:layout_weight="1" android:scrollbars="vertical" android:footerDividersEnabled="true" style="@style/listViewStyle"/>
28 </LinearLayout>
3. And if you notice, for easier management of more complex project, I define the style and color in separate files namely styles.xml and colors.xml in RES/VALUES folder where original strings.xml is located styles.xml
01 <?xml version="1.0" encoding="UTF-8"?> 02 <!-- Styling file -->
03 <resources> 04 05 06 07 <style name="listSeparatorTextViewStyle" parent="@android:attr/listSeparatorTextViewStyle"> <item name="android:layout_height">wrap_content</item> <item name="android:layout_width">fill_parent</item> <item name="android:textSize">15dip</item>
08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
<item name="android:paddingTop">2dip</item> <item name="android:paddingBottom">3dip</item> <item name="android:paddingLeft">5dip</item> <item name="android:paddingRight">10dip</item> <item name="android:textAppearance">@android:style/TextAppearance.Small</item> <item name="android:shadowColor">#111111</item> <item name="android:shadowRadius">1</item> <item name="android:shadowDy">1</item> <item name="android:textStyle">bold</item> <item name="android:textColor">@android:color/white</item> <item name="android:background">@color/dark_blue</item> </style> <style name="listViewStyle" parent="@android:attr/listViewStyle"> <item name="android:textColor">@android:color/black</item> <item name="android:background">@color/white</item> </style> <style name="genericListItemFirstTextView"> <item name="android:textSize">15dip</item> <item name="android:textStyle">bold</item> <item name="android:textColor">@color/black</item> </style> <style name="genericListItemSecondTextView"> <item name="android:textSize">13dip</item> <item name="android:textColor">@color/grey/item> </style> <style name="genericListItemShoutTextView">
34 35 36
37 </resources>
colors.xml
01 <?xml version="1.0" encoding="utf-8"?> 02 <resources> 03 04 05 06 07 08 09 <color name="white">#fff</color> <color name="black">#000</color> <color name="red">#c6360a</color> <color name="green">#688f2b</color> <color name="orange">#f48905</color> <color name="dark_blue">#003366</color> <color name="grey">#888888</color>
10 </resources>
strings.xml
01 <?xml version="1.0" encoding="utf-8"?> 02 <!-- all the strings required for the app arranged alphabetically-->
03 <resources> 04 05 06 07 08 09 <!-- A --> <string name="app_name">dummy test</string> <!-- B --> <!-- C --> <string name="create_test_activity_title">Choose your next test</string> <string name="create_test_activity_help_button">Help</string>
10 11
12 </resources>
4. Create the layout for the individual item in the list. Name it generic_list_item.xml and put it inside res/layout folder.
01 <?xml version="1.0" encoding="utf-8"?> 02 <LinearLayout 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="8dip" android:paddingRight="8dip" android:paddingTop="5dip" android:paddingBottom="8dip" android:orientation="horizontal" > <ImageView android:id="@+id/left_icon" android:layout_width="32dip" android:layout_height="32dip" android:src="@drawable/any_32_32_icon_in_png" android:scaleType="fitCenter" android:gravity="center_horizontal" android:layout_marginTop="3dip" /> <LinearLayout android:layout_width="fill_parent"
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
android:layout_height="wrap_content" android:orientation="vertical" android:paddingLeft="8dip" > <TextView android:id="@+id/firstLineTextView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="2dip" android:textAppearance="@style/genericListItemFirstTextView" android:singleLine="true" android:ellipsize="marquee"/> <ProgressBar android:id="@+id/progress_horizontal" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:max="100" android:progress="50" android:visibility="gone" /> <TextView android:id="@+id/secondLineTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="1" android:scrollHorizontally="true" android:ellipsize="marquee"
48 49
50 </LinearLayout>
5. create adapter class that will populate listview with custom data
01 public class CreateTestAdapter extends ArrayAdapter<CreateTestOption> { 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 } @Override public View getView(int position, View convertView, ViewGroup parent) { if (DEBUG) Log.d(TAG, "start getView()"); final ViewHolder holder; View v = convertView; if (v == null) { public static final String TAG = CreateTestAdapter.class.getSimpleName(); public static final boolean DEBUG = true; private ArrayList<CreateTestOption> tests; private LayoutInflater mInflater; private int layoutResource; public CreateTestAdapter(Context context, int textViewResourceId, ArrayList<ViewCreateTestActivity.CreateTestOption> mOptions) { super(context, textViewResourceId, mOptions); if (DEBUG) Log.d(TAG, "create UserTestCategoryAdapter(xxx) "); this.tests = mOptions; if (DEBUG) Log.d(TAG, "set up LayoutInflater from context"); this.mInflater = LayoutInflater.from(context); this.layoutResource = textViewResourceId;
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 }
if (DEBUG) Log.d(TAG, "mInflater inflate history_list_item"); v = mInflater.inflate(layoutResource, null); if (DEBUG) Log.d(TAG, "set up viewHolder"); holder = new ViewHolder(); holder.icon = (ImageView) v.findViewById(R.id.left_icon); holder.firstLine = (TextView) v.findViewById(R.id.firstLineTextView); holder.timeTextView = (TextView) v.findViewById(R.id.secondLineTextView); if (DEBUG) Log.d(TAG, "attach viewHolder to convertview"); v.setTag(holder); }else { // Get the ViewHolder back to get fast access to the TextView // and the ImageView. holder = (ViewHolder) v.getTag();
CreateTestOption c = tests.get(position); if (c != null) { if (DEBUG) Log.d(TAG, "t is not null"); //loading first line holder.firstLine.setText(c.getName()); holder.firstLine.setVisibility(View.VISIBLE); //loading second line holder.timeTextView.setText(c.getDescription()); holder.timeTextView.setVisibility(View.VISIBLE); //loading icon //TODO make mechanism so the icon will appear differently holder.icon.setImageResource(R.drawable.icon_done_32x32);
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 } } }
} else { // This is going to be a shout then. if (DEBUG) Log.d(TAG, "t is null"); holder.icon.setImageResource(R.drawable.ic_menu_shout); holder.firstLine.setVisibility(View.GONE); } //TODO create stringformatter if (DEBUG) Log.d(TAG, "return v"); return v;
private static class ViewHolder { ImageView icon; TextView firstLine; TextView timeTextView;
6. create activity class (at last). for this exercise, just put it in src folder and name it CreateTestActivity.java This will bind together the layout for activity class,layout for individual list item and adapter for each listitem
01 public class CreateTestActivity extends ListActivity { 02 03 04 05 06 public static final String TAG = CreateTestActivity.class .getSimpleName(); public static final boolean DEBUG = true; private ArrayList<CreateTestOption> m_options = null; private CreateTestAdapter m_adapter;
07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
private Runnable createTestActivity; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.create_test_activity); //ListView list = getListView(); //no need since we use ListActivity instead of activity ensureUi(); //generate the UI and populate its content } private void getCreateTestOptions() { try { m_options = new ArrayList<CreateTestOption>(); //we generate the value here, in reality, you should retrieve //the value from other mechanism such as database or web service CreateTestOption c1 = new CreateTestOption(); c1.setName("Quick Start"); c1.setDescription("Automatically generate a test in a flash"); CreateTestOption c2 = new CreateTestOption(); c2.setName("Recommended Package"); c2.setDescription("Choose from 3 recommended packages"); CreateTestOption c3 = new CreateTestOption(); c3.setName("Design Your Own"); c3.setDescription("Manually customize your own test"); m_options.add(c1); m_options.add(c2); m_options.add(c3);
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 } }
//loading the value together with UI thread //preventing the 'freeze' or some sort runOnUiThread(returnRes); if (DEBUG) Log.d(TAG, "getTestCategories() ends");
private Runnable returnRes = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "returnRes runable run() start"); if (m_options != null && m_options.size() > 0) { if (DEBUG) Log.d(TAG, "m_tests got something"); m_adapter.notifyDataSetChanged(); if (DEBUG) Log.d(TAG, "m_adapter.notifydatasetchanged() since m_tests got something"); for (int i = 0; i < m_options.size(); i++) m_adapter.add(m_options.get(i)); } m_adapter.notifyDataSetChanged(); if (DEBUG) Log.d(TAG, "m_adapter.notifydatasetchanged() after dismiss m_progressdialog");
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 };
private void ensureUi() { if (DEBUG) Log.d(TAG, "ensureUi() start"); if (DEBUG) Log.d(TAG, "create m_options"); m_options = new ArrayList<CreateTestOption>(); if (DEBUG) Log.d(TAG, "calling CreateTestAdapter()"); this.m_adapter = new CreateTestAdapter(this, R.layout.generic_list_item, m_options); if (DEBUG) Log.d(TAG, "listView=getListView()"); ListView listView = getListView(); if (DEBUG) Log.d(TAG, "lisview setAdapter this.m_adapter"); listView.setAdapter(this.m_adapter); listView.setSmoothScrollbarEnabled(true); if (DEBUG) Log.d(TAG, "initiate new viewTest = new Runable"); createTestActivity = new Runnable() { public void run() { getCreateTestOptions(); } }; if (DEBUG) Log.d(TAG, "create new thread with viewTestRunable"); Thread thread = new Thread(null, createTestActivity, "MagentoBackground"); if (DEBUG) Log.d(TAG, "thread start()"); thread.start(); listView.setOnItemClickListener(new OnItemClickListener() { @Override
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
public void onItemClick(AdapterView<?> adapter, View view, int position, long arg3) { Object obj = (Object)m_adapter.getItem(position); if (obj != null) { //TODO set this intent creation based on the unique parameter of the each CreateTestOption class Intent intent = new Intent(); if (position == 2) { intent.setClass(ViewCreateTestActivity.this, placeholderActivity2.class); }else if (position == 1){ intent.setClass(ViewCreateTestActivity.this, placeholderActivity1.class); }else if (position == 0 ) { intent.setClass(ViewCreateTestActivity.this, placeholderActivity0.class); } startActivity(intent); } } }); }
99 }
05 import android.widget.TextView; 06 07 public class placeholderActivity1 extends Activity { 08 09 10 11 12 13 14 15 16 } } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText("This is placeholder class #1"); setContentView(tv);
you can do that for the remaining placeholderActivity0 and placeholderActivity2 class. In essence, this will be the target class that you intend to reach upon clicking the list. 8. do not forget to define activity class in in manifest.xml
01 <?xml version="1.0" encoding="utf-8"?> 02 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 03 04 05 06 07 08 09 10 android:icon="@drawable/icon" android:label="@string/app_name" > package="com.combankmed.android" android:versionName="2010-08-02" android:versionCode="2010080200"> <application
11
12
13 <activity android:name=".placeholderActivity0" android:screenOrientation="portrait"> 14 <activity android:name=".placeholderActivity1" android:screenOrientation="portrait"> 15 <activity android:name=".placeholderActivity2" android:screenOrientation="portrait"> 16 17 18 19 20 21 22 23 </application> <uses-sdk android:minSdkVersion="4" /> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
24 </manifest>
List View and List Adapter If you want to show a List, there are two ways to do that: ListView and ListActivity. Both ListView and ListActivity can add items by using ListAdapter. There are many kinds of ListAdapter, which are shown in the list below:
ArrayAdapter<T> : A ListAdapter that manages a ListView backed by an array of arbitrary objects. BaseAdapter : Common base class of common implementation for an Adapter that can be used in both ListView and Spinner. CursorAdapter : Adapter that exposes data from a Cursor to a ListView widget. HeaderViewListAdapter : ListAdapter used when a ListView has header views. ResourceCursorAdapter : An easy adapter that creates views defined in an XML file. SimpleAdapter : An easy adapter to map static data to views defined in an XML file. SimpleCursorAdapter : An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file. WrapperListAdapter : List adapter that wraps another list adapter. The wrapped adapter can be retrieved by calling !getWrappedAdapter(). ListAdapter : Extended Adapter that is the bridge between a ListView and the data that backs the list.
A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
Define a ListView
When you want to display your list, you should define a ListView in one of xml files that you want to show. An example is given below.
<ListView android:id="@+id/test_list" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dpi" android:layout_marginRight="10dpi" android:layout_marginTop="10dpi" android:layout_marginBottom="10dpi" android:visibility="invisible" android:cacheColorHint="#00000000"> </ListView>
As you can see, you can define width/height, margin in each direction, and visibility. When the user chooses a list item, sometimes that list item is shown as black. If you want to prevent this, you can use 'cacheColorHint'.
These are layouts that already-defined at Android.R.layout and you can use at ListAdapter. Here is the example by using one of default layout 'simple_list_item_1'
Toggle line numbers
1 ListView list = (ListView)findViewById(R.id.test_list); 2 3 list.setAdapter(new ArrayAdapter<String>(this, 4 android.R.layout.simple_list_item_1, mStrings)); 5 6 list.setTextFilterEnabled(true);
mStrings are string array that has information, and I use ArrayAdapter for fill out.
I defined two text view for displaying each counties name and vaule. After you defined these value, you can fill out your list.
Toggle line numbers
1 ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>(); 2 3 HashMap<String, String> item; 4 for (int i = 0; i < 31; i++) { 5 item = new HashMap<String, String>(); 6 item.put("Name", "Any names are possible~~~~" ); 7 item.put("currencyValue", "Any string values are possible" ); 8 list.add(item); 9 } 10 11 SimpleAdapter notes = new SimpleAdapter(this, list, R.layout.row, 12 new String[] { "Name", "currencyValue" }, new int[] {R.id.Name, R.id.currencyValue }); 13 setListAdapter(notes);
This time I use SimpleAdapter inside of ListActivity. The structure of SimpleAdapter class is (activity, ArrayList<Hashmap<String, (some_type)>> ,layout,keys for hashing(String array), IDs that are mapped(int array))
Add a cursor
Now, you can display your list, but you program will do nothing when user choose one list item from your list. But once you write OnListItemClick function, you can make a new action(make an intent for changing page/moving info/etc).
Toggle line numbers
1 2 id) { 3 4 5 @Override protected void onListItemClick(ListView listView, View view, int position, long super.onListItemClick(listView, view, position, id); // do anything that you want!! }
1 private SimpleCursorAdapter myAdapter; 2 3 @Override 4 public void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 Cursor cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null); 7 startManagingCursor(cursor); 8 9 String[] columns = new String[] {People.NAME, People.NUMBER}; 10 int[] names = new int[] {R.id.contact_name, R.id.phone_number}; 11 12 myAdapter = new SimpleCursorAdapter(this, R.layout.contact, cursor, columns, names); 13 setListAdapter(myAdapter); 14 } 15 16 @Override 17 protected void onListItemClick(ListView listView, View view, int position, long id) { 18 super.onListItemClick(listView, view, position, id); 19 20 //Switch to second page when next button is clicked 21 Intent i = new Intent(); 22 Bundle extras = getIntent().getExtras(); 23 Cursor cursor = (Cursor) myAdapter.getItem(position); 24 25 //define which page is next 26 i.setClassName("com.sms.Arabic", "com.sms.Arabic.SMSSender"); 27 //add data to intent as extras 28 StringBuilder app = new StringBuilder(""); 29 30 if(!extras.getString("sender").equals("")){ 31 app.append(extras.getString("sender")); 32 app.append(";"); 33 } 34 35 String phoneNum = cursor.getString(cursor.getColumnIndex(People.NUMBER)); 36 if(phoneNum!=null){ 37 phoneNum = number_modify(phoneNum); 38 app.append(phoneNum); 39 i.putExtra("sender", app.toString()); 40 //start the next activity, and have it return a result 41 startActivity(i); 42 finish(); 43 } 44 else{ 45 Toast.makeText(this, "This contacts has no number", Toast.LENGTH_SHORT).show(); 46 } 47 }
This example queries all of the contact list, and displays all of them. This time I use a SimpleCursorAdapter inside a ListActivity. (The format of SimpleCursorAdapter is (ListActivity, layout file name, cursor, columns(String array), names for matching(int array)) ) When the user click one of the list, it create an activity with selected contact information.
arrayadapter.
Android AutoCompleteTextView Example
February 10, 2010 in Android Tutorial, AutoCompleteTextView, Textview by Sasikumar In android, we can show a string items in autocompletetextview. So that items will display according to the characters we have give. Ex:- If we are giving an it will show all the items starts with an. Example for AutoCompleteTextView :view source print?
01 <?xml version="1.0" encoding="utf-8"?> 02 <LinearLayout android:id="@+id/LinearLayout01" 03 android:layout_width="fill_parent" 04 android:layout_height="fill_parent" 05 xmlns:android="http://schemas.android.com/apk/res/android"> 06 <AutoCompleteTextView 07 android:id="@+id/AutoCompleteTextView01" 08 android:layout_width="wrap_content" 09 android:layout_height="wrap_content" 10 android:hint="This is Hint" 11 android:width="240px" /> 12 </LinearLayout>
03 04 05 06 07 08 09 10 11 12 13 14 15 16 }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ArrayAdapter<String> arrAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, sampleACTV); AutoCompleteTextView ACTV = (AutoCompleteTextView) findViewById(R.id.AutoCompleteTextView01); ACTV.setAdapter(arrAdapter); } private static final String[] sampleACTV = new String[] { "android","androidpeople.com","iphone","blackberry" };
1 Retweet
Tags: android, arrayadapter, AutoCompleteTextView, code, example, how to, source, Textview Comments (6)
03 private ListView lv1; 04 private String lv_arr[]={"Android","iPhone","BlackBerry","AndroidPeople"}; 05 @Override 06 public void onCreate(Bundle icicle) 07 { 08 super.onCreate(icicle); 09 setContentView(R.layout.main); 10 lv1=(ListView)findViewById(R.id.ListView01); 11 // By using setAdpater method in listview we an add string array in list. 12 lv1.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1 , lv_arr));
13 } 14 }
You can also customize your listview. Click here to see custom listview example The output will look like
Retweet
Tags: adapter, android, array, arrayadapter, code, example, how to, list, Listview, source, view Comments (62)
13 14 15 16 17 18 } }
Spinner s = (Spinner) findViewById(R.id.Spinner01); ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, array_spinner); s.setAdapter(adapter);
01 private ArrayAdapter<String> dataAdapter; 02 03 /** Called when the activity is first created. */ 04 @Override 05 public void onCreate(Bundle savedInstanceState) 06 { 07 08 09 10 11 12 13 14 15 16 } setListAdapter(dataAdapter); dataAdapter = new ArrayAdapter<String>(this, R.layout.item, R.id.itemName); dataAdapter.add("apple"); dataAdapter.add("orange"); dataAdapter.add("tomato"); super.onCreate(savedInstanceState);
A ListActivity is a form of Activity, but automatically provides a ListView. The method setListAdapter is provided by the ListActivity class and will set the adapter of the ListView. Running this code alone should produce a list looking like this:
The activity also provides an options menu that is accessible when the menu key is pressed. Accessible from the menu is the option to add and remove items from the list. Selecting the add options pops open the following dialog:
The code that actually adds the contents from the dialog to the ListView is inside the DialogInterface.OnClickListener associated with the add button:
view source print?
01 builder.setPositiveButton(R.string.addButtonLabel, 02 03 { 04 05 06 07 08 09 10 11 12 13 14 15 EditText timesField = (EditText) source .findViewById(R.id.timesField); Integer times = Integer.valueOf(timesField.getText() .toString()); public void onClick(DialogInterface dialog, int which) { Dialog source = (Dialog) dialog; EditText nameField = (EditText) source .findViewById(R.id.itemField); String name = nameField.getText().toString(); new DialogInterface.OnClickListener()
16 17 18 19 20 21 22 23 24 25 26 }); } } dialog.dismiss(); } if ((name.length() > 0) && (times > 0)) { for (int count = 0; count < times; count++) { dataAdapter.add(name);
Lines 8 to 10 is just getting the string to add to the list. Lines 12 to 15 is getting the value in the times field. In Lines 17 to 23, if the item is given and the specified number of times is greater than zero, then the item is added however many times was specified. Line 21 is where the item is actually added to the list. Notice that the item is added to the adapter, not the view. This is ALL that is required to make the item to add to the list. Since back in onCreate, the adapter was already set as the ListViews adapter, will automatically cause the ListView to update. Selecting the remove option on the menu removes the last item from the list. As there is no dialog required, the code that does this is back in onOptionsItemSelected. More specifically, it is done by this part of the method:
1 case REMOVE_ITEM: 2 3 4 5 break; dataAdapter.remove( dataAdapter.getItem( dataAdapter.getCount() - 1));
Again, notice that the item is removed by calling remove on the adapter, not the ListView. The view is automatically updated when the item is removed. PROGRAM Src
A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
import import import import import import import import import import import import import
android.app.Activity; android.app.AlertDialog; android.app.Dialog; android.app.ListActivity; android.content.DialogInterface; android.content.res.Resources; android.os.Bundle; android.view.Menu; android.view.MenuItem; android.view.View; android.view.ViewGroup; android.widget.ArrayAdapter; android.widget.EditText;
public class ArrayAdapterData extends ListActivity { private static final int ADD_ITEM = 0; private static final int REMOVE_ITEM = 1; private static final int EXIT_ITEM = 2; private ArrayAdapter<String> dataAdapter; private Dialog editorDialog = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); dataAdapter = new ArrayAdapter<String>(this, R.layout.item, R.id.itemName); dataAdapter.add("apple"); dataAdapter.add("orange"); dataAdapter.add("tomato"); setListAdapter(dataAdapter); } public boolean onCreateOptionsMenu(Menu menu) { Resources resource = getApplicationContext().getResources(); menu.add(Menu.NONE, ADD_ITEM, ADD_ITEM, resource.getText(R.string.ADD_ITEM)).setIcon(R.drawable.add); menu.add(Menu.NONE, REMOVE_ITEM, REMOVE_ITEM, resource.getText(R.string.REMOVE_ITEM)).setIcon(R.drawable.remove); menu.add(Menu.NONE, EXIT_ITEM, EXIT_ITEM, resource.getText(R.string.EXIT_ITEM)).setIcon(R.drawable.exit); return true; } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case ADD_ITEM: showDialog(0); break; case REMOVE_ITEM: dataAdapter.remove(dataAdapter.getItem(dataAdapter.getCount() - 1)); break; case EXIT_ITEM:
finish(); } return false; } @Override protected Dialog onCreateDialog(int id) { Dialog editor = editorDialog; if (editorDialog == null) { editor = createEditorDialog(); } return editor; } private Dialog createEditorDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.addDialogTitle); View content = getLayoutInflater().inflate(R.layout.editor, (ViewGroup) findViewById(R.id.editLayout)); builder.setView(content); builder.setPositiveButton(R.string.addButtonLabel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Dialog source = (Dialog) dialog; EditText nameField = (EditText) source .findViewById(R.id.itemField); String name = nameField.getText().toString(); EditText timesField = (EditText) source .findViewById(R.id.timesField); Integer times = Integer.valueOf(timesField.getText() .toString()); if ((name.length() > 0) && (times > 0)) { for (int count = 0; count < times; count++) { dataAdapter.add(name); } } dialog.dismiss(); } }); builder.setNegativeButton(R.string.cancelButtonLabel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } });
return builder.create(); } }
Layout Editor.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/editLayout" android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical"> <TableLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:fitsSystemWindows="true" android:orientation="horizontal" android:padding="5dp" gravity="center_horizontal"> <TableRow android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center_horizontal"> <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/nameLabel" android:text="@string/nameLabel" android:gravity="right|center_vertical" android:layout_marginRight="5dp" /> <EditText android:layout_height="fill_parent" android:id="@+id/itemField" android:layout_width="fill_parent" android:width="200dp" /> </TableRow> </TableLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="fill_parent" android:orientation="horizontal" android:gravity="center_horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/timesLabel" android:text="@string/timesLabel" android:gravity="right|center_vertical" android:layout_marginRight="5dp" /> <EditText android:text="1" android:id="@+id/timesField" android:width="100dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:digits="0123456789" /> </LinearLayout> </LinearLayout> Item.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="wrap_content" android:orientation="horizontal" android:paddingLeft="5dp" android:paddingRight="5dp"> <TextView android:id="@+id/itemName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Test view" />
</LinearLayout>
Values String.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="applicationName">String List</string> <string name="priceFormat">{0,number, currency}</string> <!-- Options menu --> <string name="ADD_ITEM">Add to End</string> <string name="REMOVE_ITEM">Remove Last</string> <string name="EXIT_ITEM">Exit</string> <!-- Parameters for the "Add Item" dialog --> <string name="addDialogTitle">Add Item</string> <string name="nameLabel">Item </string> <string name="priceLabel">Price </string> <string name="timesLabel">Times</string> <!-- Labels for the button --> <string name="addButtonLabel">Add</string> <string name="cancelButtonLabel">Cancel</string> </resources>
CursorAdapter: Adapter that exposes data from a Cursor to a ListView widget. The Cursor must
include a column named "_id" or this class will not work.
android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtName" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtPhone" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtDisplayName" /> </LinearLayout>
Explanation This would just give us 3 TextView on vertical order, this would be our custom row therefore on your application if you want to customize the row then this is the file that you might want to work upon.
Main.java
public class Main extends ListActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Cursor contactsCursor = this.managedQuery(People.CONTENT_URI, null, null, null, null); this.setListAdapter(new MyContactsAdapter(this,contactsCursor)); } private class MyContactsAdapter extends CursorAdapter{ private Cursor mCursor; private Context mContext; private final LayoutInflater mInflater; public MyContactsAdapter(Context context, Cursor cursor) { super(context, cursor, true); mInflater = LayoutInflater.from(context); mContext = context; } @Override public void bindView(View view, Context context, Cursor cursor) { TextView t = (TextView) view.findViewById(R.id.txtName); t.setText(cursor.getString(cursor.getColumnIndex(People.NAME))); t = (TextView) view.findViewById(R.id.txtDisplayName);
t.setText(cursor.getString(cursor.getColumnIndex(People.DISPLAY_NAME))); t = (TextView) view.findViewById(R.id.txtPhone); t.setText(cursor.getString(cursor.getColumnIndex(People.NUMBER))); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { final View view = mInflater.inflate(R.layout.custom_list, parent, false); return view; } } }
Explanation Query our contacts table Cursor contactsCursor = this.managedQuery(People.CONTENT_URI, null, null, null, null); Set the adapter for our ListView this.setListAdapter(new MyContactsAdapter(this,contactsCursor)); We create a class for our custom adapter named MyContactsAdapter extending it to CursorAdapter (There are a lot of adapter that you could extend upon) private class MyContactsAdapter extends CursorAdapter We get the LayoutInflater from the calling context, what this does is that it will inflate your xml to codes via View object. see newView function mInflater = LayoutInflater.from(context); On newView function we inflate our layout to the binded view inside CursorAdapter final View view = mInflater.inflate(R.layout.custom_list, parent, false); At this point we have our custom_list as the layout of our ListActivity, now what we need is to use it on every row, you would do it with bindView function public void bindView(View view, Context context, Cursor cursor) { ..... } The following should be just binding our TextView in xml to our codes and getting values from our cursor and putting that value to the respective TextView TextView t = (TextView) view.findViewById(R.id.txtName); t.setText(cursor.getString(cursor.getColumnIndex(People.NAME)));
Notes Do note that we extend to CursorAdapter here and it might be different on other adapter, like for ArrayAdapter you will use getView function, good luck....
ResourceCursorAdapter: An easy adapter that creates views defined in an XML file. You can
specify the XML file that defines the appearance of the views.
Class: android.widget.ResourceCursorAdapter
An easy adapter that creates views defined in an XML file. You can specify the XML file that defines the appearance of the views.
Inheritance
Superclass tree:
Implements:
Methods
ResourceCursorAdaptertop
public ResourceCursorAdapter(Context context, int layout, Cursor c) Constructor. Parameters: @param context The context where the ListView associated with this SimpleListItemFactory is running A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
@param layout resource identifier of a layout file that defines the views for this list item. Unless you override them later, this will define both the item views and the drop down views. Related Links: Google Code Search Stack Overflow
ResourceCursorAdaptertop
public ResourceCursorAdapter(Context context, int layout, Cursor c, boolean autoRequery) Constructor. Parameters: @param context The context where the ListView associated with this SimpleListItemFactory is running @param layout resource identifier of a layout file that defines the views for this list item. Unless you override them later, this will define both the item views and the drop down views. @param c The cursor from which to get the data. @param autoRequery If true the adapter will call requery() on the cursor whenever it changes so the most recent data is always displayed. Related Links: Google Code Search Stack Overflow
newDropDownViewtop
o
@Override
public View newDropDownView(Context context, Cursor cursor, ViewGroup parent) Makes a new drop down view to hold the data pointed to by cursor. Parameters: @param context Interface to application's global information @param cursor The cursor from which to get the data. The cursor is already moved to the correct position. @param parent The parent to which the new view is attached to Return: @return the newly created view. A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
Override hierarchy: newDropDownView from CursorAdapter Related Links: Google Code Search Stack Overflow
newViewtop
o
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) Inflates view(s) from the specified XML file. Parameters: @param context Interface to application's global information @param cursor The cursor from which to get the data. The cursor is already moved to the correct position. @param parent The parent to which the new view is attached to Return: @return the newly created view. See: @see android.widget.CursorAdapter.newView(android.content.Context, android.database.Cursor, android.view.ViewGroup) Override hierarchy: newView from CursorAdapter Related Links: Google Code Search Stack Overflow
setDropDownViewResourcetop
public void setDropDownViewResource(int dropDownLayout)
@param dropDownLayout the layout resources used to create drop down views Related Links: Google Code Search Stack Overflow
setViewResourcetop
public void setViewResource(int layout)
History
ResourceCursorAdapter
Methods
Constructors
ResourceCursorAdapter(Context,int,Cursor) ResourceCursorAdapter(Context,int,Cursor,boolean)
Members [ +/- ]
areAllItemsEnabled():boolean bindView(View,Context,Cursor):void changeCursor(Cursor):void convertToString(Cursor):CharSequence equals(Object):boolean getClass():Class<? extends Object> getCount():int getCursor():Cursor getDropDownView(int,View,ViewGroup):View getFilter():Filter getFilterQueryProvider():FilterQueryProvider getItem(int):Object getItemId(int):long getItemViewType(int):int A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
getView(int,View,ViewGroup):View getViewTypeCount():int hasStableIds():boolean hashCode():int isEmpty():boolean isEnabled(int):boolean newDropDownView(Context,Cursor,ViewGroup):View newView(Context,Cursor,ViewGroup):View notify():void notifyAll():void notifyDataSetChanged():void notifyDataSetInvalidated():void registerDataSetObserver(DataSetObserver):void runQueryOnBackgroundThread(CharSequence):Cursor setDropDownViewResource(int):void setFilterQueryProvider(FilterQueryProvider):void setViewResource(int):void toString():String unregisterDataSetObserver(DataSetObserver):void wait():void wait(long):void wait(long,int):void
Inheritance
Implements
Extends
Class
ResourceCursorAdapter
Children
SimpleCursorAdapter
ResourceCursorAdapter
extends CursorAdapter
java.lang.Object android.widget.BaseAdapter android.widget.CursorAdapter android.widget.ResourceCursorAdapter Known Direct Subclasses SimpleCursorAdapter SimpleCursorAdapter An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file.
Class Overview
An easy adapter that creates views defined in an XML file. You can specify the XML file that defines the appearance of the views.
Summary
[Expand] Inherited Constants From interface android.widget.Adapter int IGNORE_ITEM_VIEW_TYPE An item view type that causes the AdapterView to ignore the item view. int NO_SELECTION Public Constructors ResourceCursorAdapter(Context context, int layout, Cursor c) Constructor. ResourceCursorAdapter(Context context, int layout, Cursor c, boolean autoRequery) Constructor. Public Methods newDropDownView(Context context, Cursor cursor, ViewGroup parent) View Makes a new drop down view to hold the data pointed to by cursor.
newView(Context context, Cursor cursor, ViewGroup parent) View Inflates view(s) from the specified XML file. void setDropDownViewResource(int dropDownLayout)
Get a View that displays in the drop down popup the data at the specified position in the data set.
Filter getFilter()
Returns a filter that can be used to constrain data with a filtering pattern.
getFilterQueryProvider() FilterQueryProvider Returns the query filter provider used for filtering. Object long getItem(int position) getItemId(int position)
View
boolean Indicated whether the item ids are stable across changes to the underlying data. void init(Context context, Cursor c, boolean autoRequery) newDropDownView(Context context, Cursor cursor, ViewGroup parent) View Makes a new drop down view to hold the data pointed to by cursor. newView(Context context, Cursor cursor, ViewGroup parent) abstract View Makes a new view to hold the data pointed to by cursor. onContentChanged() void Called when the ContentObserver on the cursor receives a change notification. runQueryOnBackgroundThread(CharSequence constraint) Cursor Runs a query with the specified constraint. setFilterQueryProvider(FilterQueryProvider filterQueryProvider) void Sets the query filter provider used to filter the current Cursor. From class android.widget.BaseAdapter areAllItemsEnabled() boolean Are all items in this ListAdapter enabled? If yes it means all items are selectable and clickable. View getDropDownView(int position, View convertView, ViewGroup parent)
Get a View that displays in the drop down popup the data at the specified position in the data set.
getItemViewType(int position) int Get the type of View that will be created by getView(int, View, ViewGroup) for the specified item. int getViewTypeCount()
Returns the number of types of Views that will be created by getView(int, View, ViewGroup).
hasStableIds() boolean Indicated whether the item ids are stable across changes to the underlying data. boolean isEmpty() A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
isEnabled(int position) boolean Returns true if the item at the specified position is not a separator. notifyDataSetChanged() void Notifies the attached View that the underlying data has been changed and it should refresh itself. void notifyDataSetInvalidated() registerDataSetObserver(DataSetObserver observer) void Register an observer that is called when changes happen to the data used by this adapter. unregisterDataSetObserver(DataSetObserver observer) void Unregister an observer that has previously been registered with this adapter via registerDataSetObserver(DataSetObserver).
From class java.lang.Object clone() Object Creates and returns a copy of this Object. equals(Object o) boolean Compares this instance with the specified object and indicates if they are equal. finalize() void Is called before the object's memory is being reclaimed by the VM. getClass() final Class<? extends Object> Returns the unique instance of Class which represents this object's class. hashCode() int Returns an integer hash code for this object. notify() final void Causes a thread which is waiting on this object's monitor (by means of calling one of the wait() methods) to be woken up. notifyAll() final void Causes all threads which are waiting on this object's monitor (by means of calling one of the wait() methods) to be woken up. A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
toString() String Returns a string containing a concise, human-readable description of this object. wait(long millis, int nanos) final void Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object or until the specified timeout expires. wait(long millis) final void Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object or until the specified timeout expires. wait() final void Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object.
From interface android.widget.Adapter abstract getCount() int How many items are in the data set represented by this Adapter. abstract getItem(int position) Object Get the data item associated with the specified position in the data set. abstract getItemId(int position) long Get the row id associated with the specified position in the list. abstract getItemViewType(int position) int Get the type of View that will be created by getView(int, View, ViewGroup) for the specified item. abstract getView(int position, View convertView, ViewGroup parent) View Get a View that displays the data at the specified position in the data set. abstract getViewTypeCount() int
Returns the number of types of Views that will be created by getView(int, View, ViewGroup).
abstract hasStableIds() boolean Indicated whether the item ids are stable across changes to the underlying data. abstract isEmpty() A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
boolean abstract registerDataSetObserver(DataSetObserver observer) void Register an observer that is called when changes happen to the data used by this adapter. unregisterDataSetObserver(DataSetObserver observer) abstract Unregister an observer that has previously been registered with this adapter via void registerDataSetObserver(DataSetObserver). From interface android.widget.Filterable abstract getFilter() Filter
Returns a filter that can be used to constrain data with a filtering pattern.
From interface android.widget.ListAdapter abstract areAllItemsEnabled() boolean Are all items in this ListAdapter enabled? If yes it means all items are selectable and clickable. abstract isEnabled(int position) boolean Returns true if the item at the specified position is not a separator. From interface android.widget.SpinnerAdapter abstract getDropDownView(int position, View convertView, ViewGroup parent) View
Get a View that displays in the drop down popup the data at the specified position in the data set.
Public Constructors
public ResourceCursorAdapter (Context context, int layout, Cursor c)
Since: API Level 1
Constructor.
Parameters context The context where the ListView associated with this SimpleListItemFactory is running layout resource identifier of a layout file that defines the views for this list item. Unless you override them later, this will define both the item views and the drop down views.
Constructor.
Parameters context layout c autoRequery The context where the ListView associated with this SimpleListItemFactory is running resource identifier of a layout file that defines the views for this list item. Unless you override them later, this will define both the item views and the drop down views. The cursor from which to get the data. If true the adapter will call requery() on the cursor whenever it changes so the most recent data is always displayed.
Public Methods
public View newDropDownView (Context context, Cursor cursor, ViewGroup parent)
Since: API Level 1
Makes a new drop down view to hold the data pointed to by cursor.
Parameters context Interface to application's global information cursor The cursor from which to get the data. The cursor is already moved to the correct position. parent The parent to which the new view is attached to Returns
Returns
See Also
newView(android.content.Context, android.database.Cursor, ViewGroup)
android.widget.ResourceCursorAdapter
package android.widget;
18
19
import android.content.Context;
20
import android.database.Cursor;
21
import android.view.View;
22
import android.view.ViewGroup;
23
import android.view.LayoutInflater;
An easy adapter that creates views defined in an XML file. You can specify the XML file that defines the appearance of the views.
29
30
31
32
33
34
35
Constructor. Parameters:
context The context where the ListView associated with this SimpleListItemFactory is running layout resource identifier of a layout file that defines the views for this list item. Unless you override them
later, this will define both the item views and the drop down views.
45
46
public
47
super(context, c);
48
49
50
Constructor. Parameters:
context The context where the ListView associated with this SimpleListItemFactory is running layout resource identifier of a layout file that defines the views for this list item. Unless you override them
later, this will define both the item views and the drop down views.
c The cursor from which to get the data. autoRequery If true the adapter will call requery() on the cursor whenever it changes so the most recent data
is always displayed.
64
65
66
super(context, c, autoRequery);
67
68
69
Inflates view(s) from the specified XML file. A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
See also:
CursorAdapter.newView(android.content.Context,android.database.Cursor,android.view. ViewGroup)
76
77
@Override
78
public View
79
80
81
82
@Override
83
public View
84
85
public void
setViewResource(int layout) {
mLayout = layout;
94
100
101
public void
setDropDownViewResource(int dropDownLayout) {
102
mDropDownLayout = dropDownLayout;
103
104
SimpleAdapter: An easy adapter to map static data to views defined in an XML file. You can
specify the data backing the list as an ArrayList of Maps. Each entry in the ArrayList corresponds to one row in the list.
Here's another way to make a simple list, whose items have an icon and a line of text. Use SimpleAdapter and the list item layout is a TextView.
res/layout/list_item.xml:
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/list_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:gravity="center_vertical" android:paddingLeft="5dip" android:minHeight="?android:attr/listPreferredItemHeight" android:drawableLeft="@drawable/icon" android:drawablePadding="10dip"/>
IconList.java
package com.kurtchen.android.iconlist; import android.app.ListActivity;
public class IconListActivity extends ListActivity implements ViewBinder { private static final String LIST_TEXT = "list_text"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initList(); } private void initList() { List<Map<String, ListItem>> listData = new ArrayList<Map<String, ListItem>>(3); Map<String, ListItem> itemData1 = new HashMap<String, ListItem>(1); ListItem listItem1 = new ListItem(); listItem1.text = getString(R.string.menu_item1); listItem1.icon = R.drawable.facebook; itemData1.put(LIST_TEXT, listItem1); listData.add(itemData1); Map<String, ListItem> itemData2 = new HashMap<String, ListItem>(1); ListItem listItem2 = new ListItem(); listItem2.text = getString(R.string.menu_item1); listItem2.icon = R.drawable.flickr; itemData2.put(LIST_TEXT, listItem2); listData.add(itemData2); Map<String, ListItem> itemData3 = new HashMap<String, ListItem>(1); ListItem listItem3 = new ListItem(); listItem3.text = getString(R.string.menu_item1); listItem3.icon = R.drawable.twitter; itemData3.put(LIST_TEXT, listItem3); listData.add(itemData3); SimpleAdapter simpleAdapter = new SimpleAdapter(this, listData, R.layout.list_item, new String[] {
LIST_TEXT }, new int[] { R.id.list_text }); simpleAdapter.setViewBinder(this); setListAdapter(simpleAdapter); } @Override public boolean setViewValue(View view, Object data, String stringRepresetation) { ListItem listItem = (ListItem)data; TextView menuItemView = (TextView)view; menuItemView.setText(listItem.text); menuItemView.setCompoundDrawablesWithIntrinsicBounds(this.getResources().getDrawable( listItem.icon), null, null, null); return true; } private class ListItem { public String text; public int icon; } }
SimpleAdapter, as its name indicated, is just a simple implementation. If we want to make changes in list dynamically, we may need to write a custom adaptor.
SpinnerAdapter: Extended Adapter that is the bridge between a Spinner and its data. A spinner
adapter allows to define two different views: one that shows the data in the spinner itself and one that shows the data in the drop down list when the spinner is pressed.
WrapperListAdapter: List adapter that wraps another list adapter. The wrapped adapter can be
retrieved by calling getWrappedAdapter().
A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
I was working with a Spinner with a lot of rows fetched from a database, and wanted to put a bit of padding around each item to make it easier for the user to select them. So I went into my res\layout\spinner_view_row.xml (which controls how the Spinner rows display) and added this: android:padding="5dip" Then, when I went and re-ran my app, what used to look like this:
.. Ooops.
Looks like a condom doesn't it. Not what I was trying to achieve, really. If I made the padding large enough, it will also look like that before I've even selected anything. Not what I wanted at all. But I do want that padding around each item in my Spinner, otherwise my users will have too much trouble choosing items from my latest super-dooper, take-the-world-by-storm, #1 in the world market app, and it might not stay #1 for long at all. Luckily, the answer is really, really simple. You might recogise the below as the piece of code that binds a cursor from the database (containing all the items we want to display), to the xml view spinner_view_row, located at res\layout\spinner_view_row.xml (this is the xml file A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
final SimpleCursorAdapter ingredientAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, ingredientsCursor, from, to); ingredientAdapter.setDropDownViewResource(R.layout.spinner_view_row); spnIngredients.setAdapter(ingredientAdapter);
All we need to do to avoid the stretchy condom spinner arrow is to define another xml view in res\layout\ and call it something like spinner_view_closed, then paste into it the same code that you have in spinner_view_row. Simply then customise this xml to have less padding, or a smaller text size for instance, then replace the reference to
simple_spinner_item
.. and your new Spinner will look like this when open:
The Android platform offers a wide variety of UI widgets, small visual construction blocks that you can glue together to present users with complex and useful interfaces. However applications often need higher-level visual components. To meet that need, and to do so efficiently, you can combine multiple standard widgets into a single, reusable component. For example, you could create a reusable component that contains a progress bar and a cancel button, a panel containing two buttons (positive and negative actions), a panel with an icon, a title and a description, and so on. You can create UI components easily by writing a custom View, but you can do it even more easily using only XML. In Android XML layout files, each tag is mapped to an actual class instance (the class is always a subclass of View, The UI toolkit lets you also use three special tags that are not mapped to a View instance: <requestFocus />, <merge /> and <include />. This article shows how to use <include /> to create pure XML visual components. The <include /> element does exactly what its name suggests; it includes another XML layout. Using this tag is straightforward as shown in the following example:
<com.android.launcher.Workspace android:id="@+id/workspace" android:layout_width="fill_parent" android:layout_height="fill_parent" launcher:defaultScreen="1"> <include android:id="@+id/cell1" layout="@layout/workspace_screen" /> <include android:id="@+id/cell2" layout="@layout/workspace_screen" /> <include android:id="@+id/cell3" layout="@layout/workspace_screen" /> </com.android.launcher.Workspace>
In the <include /> only the layout attribute is required. This attribute, without the android namespace prefix, is a reference to the layout file you wish to include. In this example, the same layout is included three times in a row. This tag also lets you override a few attributes of the included layout. The above example shows that you can use android:id to specify the id of the root view of the included layout; it will also override the id of the included layout if one is defined. Similarly, you can override all the layout parameters. This means that any android:layout_* attribute can be used with the <include /> tag. Here is an example:
Let me know if you have any issues or questions. This works with, and probably requires, a AVD version of 2.1 or thereabouts.
contents of droidTest1.java:
package androidforbeginners.droidTest1; import android.app.Activity; import android.os.Bundle; public class droidTest1 extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
contents of main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="combining layouts" /> <include android:id="@+id/cell1" layout="@layout/layout2" /> <include android:id="@+id/cell2" layout="@layout/layout3" />
</LinearLayout>
Contents of layout2.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="100px"
android:background="#0033cc" > <TextView android:layout_width="fill_parent" android:layout_height="40px" android:text="layout2" /> <CheckBox android:layout_width="fill_parent" android:layout_height="40px" /> </LinearLayout>
Contents of layout3.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="100px" android:background="#0066cc" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="layout3" /> <CheckBox android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
Output:
You could also include multiple occurrences of the one layout in your main.xml like this if you wanted: contents of main.xml (revised):
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="combining layouts" /> <include <include <include <include android:id="@+id/cell1" android:id="@+id/cell2" android:id="@+id/cell3" android:id="@+id/cell4" layout="@layout/layout2" layout="@layout/layout2" layout="@layout/layout2" layout="@layout/layout2" /> /> /> />
</LinearLayout>
Although if you do this, I can't see a way to reference individual repeating items. I think include is more including a single layout across multiple Activities.
and
<listview id="@android:id/list">
@+id/foo means you are creating an id named foo in the namespace of your application. You can refer to it using @id/foo. @android:id/foo means you are referring to an id defined in the android namespace.
The '+' means to create the symbol if it doesn't already exist. You don't need it (and shouldn't use it) when referencing android: symbols, because those are already defined for you by the platform and you can't make your own in that namespace anyway. This namespace is the namespace of the framework. for example, you need to use @android:id/list because this the id the framework expects to find.. (the framework knows only about the ids in the android namespace.)
Remember that your layout files must have lowercase names, or they won't show up in your autoComplete list of options after 'R.layout' in Eclipse when you try this :
setContentView(R.layout.test_db);
The file won't actually show up as having any errors in your package explorer (on the right by default in the IDE), but if you look down in the console (by default down the bottom), you'll see this:
Invalid file name: must contain only [a-z0-9_.]
You might see an error on your project name, but with all the folders and files it can be hard to track down the cause. When you try to run your application you will see:
'Your project contains error(s) please fix them before running your application'
.. and it won't be happy until you delete the offending file, even if you're not actively referencing it in your code.
A status bar notification is used to notify the user of a system event, like an sms being received or a new device being detected, without interrupting the user from whatever other task they might be doing with their phone. The status bar area is located at the top of the screen and the user can pull this area to expand it, and show a history of notifications.
If a Notification has been setup to include an enclosed Intent, selecting that particular notification in this expanded view can fire the Intent, taking the user to an Activity screen of the related application, or do any of the many other things that Intents can do. You can also configure the notification to alert the user with a sound, a vibration, and flashing lights on the device.
A background Service should never launch an Activity on its own in order to receive user interaction. The Service should instead create a status bar notification that will launch the Activity when selected by the user. A status bar notification should be used for any case in which a background Service needs to alert the user about an event.
Here is a simple method that creates and displays a notification when passed a string msg :
public void displayNotification(String msg) { NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); Notification notification = new Notification(R.drawable.icon, msg, System.currentTimeMillis()); // The PendingIntent will launch activity if the user selects this notification PendingIntent contentIntent = PendingIntent.getActivity(this, REQUEST_CODE, new Intent(this, ExpandNotification.class), 0); notification.setLatestEventInfo(this, "Title here", ".. And here's some more details..", contentIntent); manager.notify(NOTIFICATION_ID, notification); }