Lecture 4 - Lists, Preferences

< CS193A Android Programming

Last time: mClickCount vs. onDestroy

See how mClickCount variant in activity object is destroyed. All the UI is preserved automatically though, and keeping the UI going is a very common case.

Second Activity / finish() / onPause()


<?xml version="1.0" encoding="utf-8"?>
<!--  layouts/second.xml - layout for trivial second activity -->
<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:text="This is the second activity" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/textView1"></TextView>
    <Button android:text="Finish It!" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
</LinearLayout>

----

package edu.stanford.nick;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class SecondActivity extends Activity {
	public static final String TAG = "Second";
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		Log.v(TAG, "onCreate:" + savedInstanceState);
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.second);
		
		// Button calls finish() to end the activity
		// (similar to hitting the back button)
		Button b2 = (Button) findViewById(R.id.button1);
		b2.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				finish();
			}
		});
	}
	
	// Here we have onXXX just to log them..
	
	@Override
	public void onResume() {
		Log.v(TAG, "onResume");
		super.onResume();
	}
	
	@Override
	public void onPause() {
		Log.v(TAG, "onPause");
		super.onPause();
	}
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		Log.v(TAG, "onSaveInstanceState:" + outState);
	}

	@Override
	public void onDestroy() {
		Log.v(TAG, "onDestroy");
		super.onDestroy();
	}
}


----

Need to add in the manifest:

        ...
        <activity android:name=".SecondActivity"
                  android:label="Second Activity" >
        </activity>
        ...

----

Code to start activity from button:

		// Start the SecondActivity
		Button b2 = (Button) findViewById(R.id.button2);
		b2.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
		        Intent myIntent = new Intent(LifecycleActivity.this.getApplicationContext(),
		        		SecondActivity.class);
		        startActivityForResult(myIntent, 0);
			}
		});

List View

<?xml version="1.0" encoding="utf-8"?>
<!--  layouts/mylist.xml - ListView example -->
<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:text="List activity" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/textView1"></TextView>
    <Button android:text="Add" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
    <!--  ListView has special id @android:id/list to work with ListActivity -->
    <ListView android:layout_height="wrap_content" android:id="@android:id/list" android:layout_width="match_parent"></ListView>
</LinearLayout>


---------

package edu.stanford.nick;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

// Demonstrates a simple ListView showing data from an ArrayList.
public class MyListActivity extends ListActivity {
	// The ArrayAdpater interfaces between list view and the ArrayList of data.
	// Here the adapter is an instance var in the Activity ... not the correct
	// long-term strategy, since the activity gets destroyed.
	private ArrayAdapter<String> mAdapter;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.mylist);
		// Comment out above to use the default list-fills-screen layout.
		
		List<String> data = new ArrayList<String>();
		data.add("The Prolific Oven");
		data.add("Fraiche Yogurt");
		data.add("Patxis Pizza");
		data.add("Jing Jing");
		data.add("St. Michael's Alley");
		
		// simple_list_item_1 is a built in "layout" for single row item.
		// Later we'll make our own little layouts for one row.
		mAdapter = new ArrayAdapter<String>(
			this,
			android.R.layout.simple_list_item_1,
			data
		);
		
		setListAdapter(mAdapter);
		
		
		Button b1 = (Button) findViewById(R.id.button1);
		b1.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				addRow();
			}
		});
	}
	
	// Notification of click on a list item -- shows a toast.
	protected void onListItemClick(ListView listView, View view, int position, long id) {
		super.onListItemClick(listView, view, position, id);
		
		String string = (String) getListAdapter().getItem(position);
		Toast.makeText(this, "Behold: " + string, Toast.LENGTH_SHORT).show();
	}
	
	// Adds data to the list, via the adapter. Shows that the UI
	// sees data changes.
	// Problem: where is the data stored when this activity is gone?
	private void addRow() {
		String now = String.valueOf(System.currentTimeMillis());
		mAdapter.add(now);
	}
}

Preferences

<?xml version="1.0" encoding="utf-8"?>
<!--
  res/xml/prefs.xml Simple preferences example
  key = logical name of pref
  title/summary = human readable (use @string/... for i18n)
-->
<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:key="preferencescreen1"
  android:title="@string/pref_title"
  android:summary="@string/pref_summary">
    
  <CheckBoxPreference
    android:key="crashrandomly"
    android:title="Crash Randomly" />
            
  <ListPreference
    android:key="runpref"
    android:title="Run Preference"
    android:summary="Select one of a list of choices"
    android:entries="@array/titles1"
    android:entryValues="@array/values1" />
                        
</PreferenceScreen> 

Preferences Activity code...

package edu.stanford.nick;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;

// Trivial preferences activity
public class MyPreferenceActivity extends PreferenceActivity {
	public static final String TAG = "Lifecycle";
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.xml.prefs);
	}
	
	@Override
	public void onPause() {
		super.onPause();
		
		// Normally you don't need an onPause here -- just using it to show
		// how to retrieve the pref values in code.
		
        SharedPreferences prefs =
        		PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        
        // Here's how to grab a preference value
        boolean crashy = prefs.getBoolean("crashrandomly", true);
        String run = prefs.getString("runpref", "");
        
        System.err.println("crashy:" + crashy);
        System.err.println("run:" + run);
	}
}

No homework this week, but we'll have a real homework next week, summing up everything we've done so far