mobile programming lecture 4
DESCRIPTION
Mobile Programming Lecture 4. Resources, Selection, Activities, Intents . Announcement. Reminder: Homework 2 is due this Friday 11:59pm. You need to demo to me in class. The second deadline is Sunday 11:59pm. You need to demo to me in Monday’s class. - PowerPoint PPT PresentationTRANSCRIPT
Mobile ProgrammingLecture 4
Resources, Selection, Activities, Intents
Announcement
• Reminder: o Homework 2 is due this Friday 11:59pm. You need to
demo to me in class.o The second deadline is Sunday 11:59pm. You need to
demo to me in Monday’s class.o Please export your project (.zip) and email me.
• Midterm exam is on June 21st. It is a Friday.
Lecture 3 Review
• Why shouldn't you use Toast to debug?
• How should you debug?
Agenda
Referencing @string resources
• Setters and Getters
• Selection Views
• Android Components - Activity
• Intents
• More on the Android Manifest File
Referencing @string Resources
All @string Resources are stored in res/values/strings.xml
You reference them in XML as "@string/string_name"
Referencing @string ResourcesYou can also reference them in Java
String buttonText = "";Resources res = getResources();buttonText = res.getString(R.string.string_name);
Referencing ResourcesYou can store an array of strings if you need a collection
instead of just a single string. This makes it an @array resource instead of @string resource!
• Open res/values/strings.xml in Resources view
• Add ... > String Arrayo enter the name of the string_array, e.g. "countries"
• Repeat until you've added all values for the collection ...o Add ... > Itemo Enter the name of the item
Setters and Getters for Views
Most of a View's attributes can be set and get programmatically
Example widget XML attribute set method get method
EditText android:text setText(String) getText()
Button android:onClick setOnClickListener(OnClickListener) -
CheckBox android:checked setChecked(Boolean) isChecked()
SeekBar android:progress setProgress(int) getProgress()
SeekBar android:max setMax(int) getMax()
Selection Widgets - SpinnerSimilar to a drop-down list
• android:spinnerModeo "dialog" or "dropdown"
• android:prompto e.g. "Select an option"o message to display when the spinner dialog is shown
only when android:spinnerMode="dialog"
• android:entrieso e.g. "@array/countries"o populate the spinner using
this array
Selection Widgets - SpinnerSimilar to a drop-down list
• android:prompto e.g. "Select an option"o message to display when the spinner dialog is shown
• android:spinnerModeo "dialog" or "dropdown"
• android:entrieso e.g. "@array/countries"o populate the spinner using
this array
If the list is static, you can again avoid Java by specifying the entries in XML!
Selection Widgets - SpinnerSimilar to a drop-down list
• android:prompto e.g. "Select an option"o message to display when the spinner dialog is shown
• android:spinnerModeo "dialog" or "dropdown"
• android:entrieso e.g. "@array/countries"o populate the spinner using
this array
If you don't like XML, you can set the entries in Java also.
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
This is the Java code. If you choose to do this, then you don't need to set the android:entries attribute
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
You should already know what this does.
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
Since you don't like XML, to do it programmatically, you need to use an Adapter.
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
This is Java stuff. If you don't know what it is, try removing it to see what happens.
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
If you have an @array resource already, then create an ArrayAdapter from that resource.
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
First argument is of type Context, you can just past the "this" keyword here (because of the state of app)
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
This is the resource that you're creating the ArrayAdapter from.
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
3rd argument expects the @id of a TextView.
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
android.R gives you resources that exist for use even before you create your app
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
So instead of creating and using your own TextView for this purpose, use this one
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
mySpinner.setAdapter(adapter); }
Attach the Adapter to the Spinner in order to populate the Spinner!
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.countries, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(adapter); }
Finally, this line of code is not required, but it makes your drop down look pretty.
Selection Widgets - Spinner
Both ways give you a Spinner which uses predetermined entries
How do you populate the Spinner at runtime, with when the entries are also determined at runtime?
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
String[] countries = new String[]{"Brazil","China","Denmark"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, countries);
mySpinner.setAdapter(adapter); }
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
String[] countries = new String[]{"Brazil","China","Denmark"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, countries);
mySpinner.setAdapter(adapter); }
Create and initialize a String array
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
String[] countries = new String[]{"Brazil","China","Denmark"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, countries);
mySpinner.setAdapter(adapter); }
Create an ArrayAdapter to populate the Spinner with
Selection Widgets - Spinnerpublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
String[] countries = new String[]{"Brazil","China","Denmark"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, countries);
mySpinner.setAdapter(adapter); }
3rd argument accepts a List of Strings
Selection Widgets - ListView
A ListView is similar to a Spinner
• they both show the user a list of items
• they both have the android:entries attribute, so they can both be set using the same @array resource or the same ArrayAdapter
Selection Widgets - ListView Adapters are used to provide the data to the ListView
object.
The adapter also defines how each row is the ListView is displayed.
You can use pre-existing layout for each row.
You can also define customized layout for each row. Extends BaseAdapter class.
Selection Widgets - ListViewA ListView is similar to a Spinner with some exceptions, to name a few:
• A Spinner is normally used for forms, a ListView not so much
• A Spinner only shows one item at a time
• A Spinner item can be "selected", a ListView item can be "clicked" or "selected"
Selection Widgets - ListViewA ListView is similar to a Spinner with some exceptions,
to name a few:
• A Spinner is normally used for forms, a ListView not so much
• A Spinner only shows one item at a time
• A Spinner item can be "selected", a ListView item can be "clicked" or "selected"
I added this in hindsight. On non-trouch-screen devices it can be selected
Events - Spinner OnItemSelected
You can set an EventListener for when the user selects an item from the Spinner
Events - Spinner OnItemSelectedmySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText() , Toast.LENGTH_SHORT).show();
}
@Overridepublic void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getApplicationContext(), "You didn't select anything" , Toast.LENGTH_SHORT).show();
}});
Events - Spinner OnItemSelectedmySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText() , Toast.LENGTH_SHORT).show();
}
@Overridepublic void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getApplicationContext(), "You didn't select anything" , Toast.LENGTH_SHORT).show();
}});
Setter method for setting the EventListener
Events - Spinner OnItemSelectedmySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText() , Toast.LENGTH_SHORT).show();
}
@Overridepublic void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getApplicationContext(), "You didn't select anything" , Toast.LENGTH_SHORT).show();
}});
Anonymous class
Events - Spinner OnItemSelectedmySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText() , Toast.LENGTH_SHORT).show();
}
@Overridepublic void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getApplicationContext(), "You didn't select anything" , Toast.LENGTH_SHORT).show();
}});
When an item is selected ...,
Events - Spinner OnItemSelectedmySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText() , Toast.LENGTH_SHORT).show();
}
@Overridepublic void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getApplicationContext(), "You didn't select anything" , Toast.LENGTH_SHORT).show();
}});
You can now reference the actual View (i.e., each entry in Spinner is a TextView)
Events - Spinner OnItemSelectedmySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText() , Toast.LENGTH_SHORT).show();
}
@Overridepublic void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getApplicationContext(), "You didn't select anything" , Toast.LENGTH_SHORT).show();
}});
The position of the view in the Adapter
Events - Spinner OnItemSelectedmySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText() , Toast.LENGTH_SHORT).show();
}
@Overridepublic void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getApplicationContext(), "You didn't select anything" , Toast.LENGTH_SHORT).show();
}});
The android:id attribute of the view
Events - Spinner OnItemSelectedmySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText() , Toast.LENGTH_SHORT).show();
}
@Overridepublic void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getApplicationContext(), "You didn't select anything" , Toast.LENGTH_SHORT).show();
}});
Cast the generic View to a TextView
Events - Spinner OnItemSelectedmySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText() , Toast.LENGTH_SHORT).show();
}
@Overridepublic void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getApplicationContext(), "You didn't select anything" , Toast.LENGTH_SHORT).show();
}});
Get the android:text value
Events - Spinner OnItemSelected• Note that this we're using the OnItemSelectedListener
instead of the OnItemClickListener for Spinner!• If you try to use OnItemClickListener you may get errors
• Also, note the difference between these two listeners and OnClickListenero OnItemClickListener
an entry in the Spinner has been clicked, don't use thiso OnClickListener
the Spinner has been clickedo OnItemSelectedListener
an entry in the Spinner has been selected
Events - ListView OnItemClick
As mentioned before, a ListView item can be clicked, or selected
In that case, you use OnItemClickListener for ListView or OnItemSelected Listener
Events - ListView OnItemClick
myListView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}});
Android Application Components
So far we've only been working with 1 of the 4 Android components, namely Activity
Android Application Components
The 4 Android application components are
1. Activity
2. Broadcast Receiver
3. Content Provider
4. Service
Activity
So far we've only been working with a single Activity
Remember, an Activity is a single screen with a user interface
Each Activity in an application is independent
Activity
An Activity is the only Android application component with a UI!
Activity
In Homework 2, you're creating a form that doesn't do anything after the form is submitted
If you want to take the user to a different screen after the form is submitted, you should add a new Activity to your app.
Activity
To add a new Activity• open the AndroidManifest.xml file
• click on the Application tab at the bottom of the window
• under the Application Nodes section, click Add ...
• select Activity
• in the Attributes for Activity section, click on the Name* link
• Enter the name of your second Activity
• Finish
You can design the UI for your second Activity e.g. add another res/layout/xml_file.xml
Now we need to figure out how to launch the second Activity B from the first Activity A
Activity
Intent
An Intent is an abstract description of an operation to be performed
You can use it to launch another Activity B from within Activity A using an Intent
Activity A Activity BIntent
Activity and Intent
...
public void onClick(View view){
Intent myIntent = new Intent(A.this, B.class);startActivity(intent);
}
...
Activity and Intent
...
public void onClick(View view){
Intent myIntent = new Intent(A.this, B.class);startActivity(intent);
}
...
The name of the Activity the app is currently running
Activity and Intent
...
public void onClick(View view){
Intent myIntent = new Intent(A.this, B.class);startActivity(intent);
}
...
The name of the Activity that should be launched
Activity and Intent
...
public void onClick(View view){
Intent myIntent = new Intent(A.this, B.class);startActivity(intent);
}
...
Launch Activity B now
Activity - Android Manifest File
• If you added the second Activity B this way, then B will be automatically added to the Android Manifest file
• If you added it some other way, then Activity B may not be in the Manifest File. This is an easy to get a Force Close when you try to launch Activity B!
• Android needs to know what Activities your app may launch
Activity - ListActivity
Sometimes the entire UI for your Activity may be a ListView
In this case, you can extend ListActivity instead of extending Activity
You don't need a layout.xml file for a ListActivity!
Activity - ListActivitypublic class MyListActivity extends ListActivity {
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.main);String[] list = new String[]{"one","two","three"};
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter); }}
Activity - ListActivitypublic class MyListActivity extends ListActivity {
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.main);String[] list = new String[]{"one","two","three"};ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter); }}
extend ListActivity instead of Activity
Activity - ListActivitypublic class MyListActivity extends ListActivity {
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.main);String[] list = new String[]{"one","two","three"};ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter); }}
We don't need to setContentView because we're extending ListActivity
Activity - ListActivitypublic class MyListActivity extends ListActivity {
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
String[] list = new String[]{"one","two","three"};ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter); }}
We don't need to setContentView because we're extending ListActivity
Activity - ListActivitypublic class MyListActivity extends ListActivity {
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
String[] list = new String[]{"Brazil","China","Denmark"};ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter); }}
We've seen this before in this lecture
Activity - ListActivitypublic class MyListActivity extends ListActivity {
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
String[] list = new String[]{"Brazil","China","Denmark"};ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter); }}
We've also seen this before in this lecture
Activity - ListActivitypublic class MyListActivity extends ListActivity {
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
String[] list = new String[]{"Brazil","China","Denmark"};ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter); }}
We call setListAdapter on this ListActivity instead of calling it on a ListView (we don't have a ListView specified in an XML file this time!)
Activity - ListActivitypublic class MyListActivity extends ListActivity {
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
String[] list = new String[]{"Brazil","China","Denmark"};ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter); }}
This is equivalent to calling this.setListAdapter(adapter);i.e., using the this keyword to refer to this instance of MyListActivity
References
• The Busy Coder's Guide to Android Development - Mark Murphy
• Android Developers
• The Mobile Lab at Florida State University