CS499 – Mobile Application Development Fall 2013 Programming the Android Platform User Interface - Continued
Menus Activities support menus Activities can: Add items to a menu Handle clicks on menu items
Menu Types Options Context Submenu Primary menu shown when user presses the menu button Context View-specific menu to be shown when user touches and hold the view Submenu A menu activated when user touches a visible menu item.
Option Menu and SubMenus
Context Menus
Creating Menus Define menu resource in XML file (/res/menu/filename.xml) Inflate menu resource using MenuInflater in appropriate onCreate…Menu() method Handling item selection in appropriate on …ItemsSelected() methods
HelloAndroidWithMenus
Creating Option Menus public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.top_menu,menu); return true; }
top_menu.xml (/res/menu) <menu … > <item android=“@+id/help” android:title=“@string/help” android:icon=“@drawable/ic_menu_help” /> <item android=“@+id/help2” android:title=“@string/help” <item android=“@+id/help3” android:title=“@string/help” android:icon=“@drawable/ic_menu_help” > </item> </menu>
Selecting Option Menu Items public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.help: // do something return true; case R.id.help2: case R.id.help3: }
Dialogs Independent subwindows used by Activities to communicate with the user Dialog subclasses AlertDialog ProgressDialog DatePickerDialog TimePickerDialog
AlertDialog
AlertDialog private final int ALERTTAG=0, PROGRESSTAG = 1; … shutdownButton.setOnClickListener( new OnClickListener() { public void onClick(View v) { showDialog(ALERTTAG); } });
onCreateDialog() protected Dialog onCreateDialog(int id, Bundle args){ … case ALERTTAG: AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(“Do you really want to exit?”) .setCancelable(false) .setPositiveButton(“Yes”, new DialogInterface.OnClickListener() { dialog.cancel(); showDialog(PROGRESSTAG); }) .setNegativeButton(“No”, new public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } });
ListView ViewGroup containing a scrollable list of selectable items List items inserted using an Adapter One of the most complicated ViewGroups to use (in my experience) Code for slide examples are in the Examples folder on Blackboard
ListView Receive data via an adapter which also defines how each row is displayed ArrayAdapter can handle data based on Arrays or java.util.list SimpleCursorAdapter can handle database related data Default layouts for row (i.e. android.R.layout.simple_list_item1) Adapter assigned to list via setAdapter method on the ListView object ListView calls getView() on the adapter for each data element
Simple Example (similar to ListView-0 online) ListView listView = (ListView) findViewById(R.id.mylist); String[] values = new String[] {“Android”, ”iPhone”, ”WindowsMobile”, ”Blackberry”, ”WebOS”, “Ubuntu”, ”Windows7”, ”Mac OS X”, ”Linux”,”OS/2”}; //Param1 – context //Param2 – row layout //Param3 – ID of the view to which data is written //Param4 – the Array of data ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, values); listView.setAdapter(adapter);
main.xml (ListView-0) Simply displays a list <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/mylist" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> Simply displays a list
ListView-1 New Features: Specifying a layout for each line. onClick listener for the items of a list Adding/removing items to the list.
ListView-1 line.xml <TextView xmlns:android= … listView = (ListView) findViewById(R.id.mylist); // Param1 - context // Param2 – xml layout file for the row myAdapter = new ArrayAdapter<String>(this, R.layout.line); listView.setAdapter(myAdapter); line.xml <TextView xmlns:android= "http://schemas.android.com/apk/ res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" android:padding="5dp" />
ListView-1 Use Toast to print out the item being touched … listView = (ListView) findViewById(R.id.mylist); // Param1 - context // Param2 – xml layout file for the row myAdapter = new ArrayAdapter<String>(this, R.layout.line); listView.setAdapter(myAdapter); listView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(getApplicationContext(), ((TextView) view).getText(), Toast.LENGTH_SHORT).show(); } }); Use Toast to print out the item being touched
ListView-1 Remove item for when pressed (and held) listView.setOnItemLongClickListener(new OnItemLongClickListener() { public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(getApplicationContext(), "Removing " + ((TextView) view).getText(), Toast.LENGTH_SHORT).show(); myAdapter.remove(myAdapter.getItem(position)); return true; } }); Remove item for when pressed (and held)
ListView-1 Use buttons to add and clear items Button addButton = (Button)findViewById(R.id.add); addButton.setOnClickListener(new AdapterView.OnClickListener() { public void onClick(View v) { String input = et.getText().toString(); myAdapter.add(input); Toast.makeText(getApplicationContext(), "Adding " + input, Toast.LENGTH_SHORT).show(); et.setText(""); } }); Button clearButton = (Button)findViewById(R.id.clear); clearButton.setOnClickListener(new AdapterView.OnClickListener() { myAdapter.clear(); Use buttons to add and clear items
ListView-3 New Features: Using ListActivity (see also ListView-2) Custom Adapters
ListActivity Extension of Activity class designed to simplify the handling of ListView If only using a list, don’t need to create XML UI Default name for the ListView: listView = (ListView)findViewById(android.R.id.list);
Custom Adapters The canned adapters are pretty generic. If you want to do anything more interesting, you need to write your own adapters. Consider adding an icon for each element of the list. Suppose I only like fruit is the name is at least 8 characters…
line.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content“ android:padding="5dp" > <ImageView android:id="@+id/image" android:layout_width="50px" android:layout_height="50px" android:layout_marginLeft="5px" android:layout_marginRight="20px" android:layout_marginTop="5px" android:src="@drawable/emo_im_undecided" /> <TextView android:id="@+id/label" android:layout_height="wrap_content" android:textSize ="30px" android:text="@+id/label" /> </LinearLayout>
Custom Adapter private class MyCustomAdapter extends BaseAdapter { private ArrayList<String> mData = new ArrayList<String>(); private LayoutInflater mInflater; public MyCustomAdapter() { mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); } public void addItem(final String item) { mData.add(item); notifyDataSetChanged(); } public void removeItem(final String item) { mData.remove(item); notifyDataSetChanged(); } public int getCount() { return mData.size(); public String getItem(int position) { return mData.get(position); public long getItemId(int position) { return position; public void clear() { mData.clear(); notifyDataSetChanged(); } public View getView(int position, View convertView, ViewGroup parent) { // next slide }
Custom Adapter See online for complete adapter… public View getView(…) { ViewHolder holder = null; if (convertView == null) { convertView = mInflater.inflate(R.layout.line, null); holder = new ViewHolder(); holder.textView = (TextView)convertView.findViewById(R.id.label); holder.imageView = (ImageView)convertView.findViewById(R.id.image); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } String s = mData.get(position); holder.textView.setText(s); if (s.length() < 4) holder.imageView.setImageResource( R.drawable.emo_im_sad); else if (s.length() < 8) R.drawable.emo_im_undecided); else R.drawable.emo_im_happy); return convertView; } public static class ViewHolder { public TextView textView; public ImageView imageView; } Holder class in Activity - Note similarity to line.xml See online for complete adapter…
Related Views: GridView – 2-d scrollable grid Spinner – also uses an adapter