1. Trang chủ
  2. » Công Nghệ Thông Tin

Lập trình Androi part 26 pps

8 254 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 8
Dung lượng 306,71 KB

Nội dung

177 177 Chapter Launching Activities and Subactivities As you’ve learned, the theory behind the Android UI architecture is that developers should decompose their application into distinct activities Each activity is implemented as an Activity, and each is reachable via intents, with a “main” activity being the one launched by the Android launcher. For example, a calendar application could have activities for viewing the calendar, viewing a single event, editing an event (including adding a new one), and so forth. This implies that one of your activities has the means to start up another activity. For example, if someone selects an event from the view-calendar activity, you might want to show the view-event activity for that event. So, you need to be able to cause the view- event activity to launch and show a specific event (the one the user chose). This chapter describes how to do that. NOTE: This chapter assumes that you know which activity you want to launch, probably because it is another activity in your own application. It’s also possible that you have a content Uri to do something, and you want your users to be able to do something with it, but you do not know up front what the options are. This situation requires more advanced handling, which I cover in my book The Busy Coders Guide to Advanced Android Development (CommonsWare, 2009). Peers and Subs One key question you need to answer when you decide to launch an activity is this: Does your activity need to know when the launched activity ends? For example, suppose you want to spawn an activity to collect authentication information for some web service you are connecting to—maybe you need to authenticate with OpenID (http://openid.net/) in order to use an OAuth service 18 CHAPTER 18: Launching Activities and Subactivities 178 (http://oauth.net/). In this case, your main activity will need to know when the authentication is complete so it can start to use the web service. On the other hand, imagine an e-mail application in Android. When the user elects to view an attachment, neither you nor the user necessarily expect the main activity to know when the user is finished viewing that attachment. In the first scenario, the launched activity is clearly subordinate to the launching activity. In that case, you probably want to launch the child as a subactivity, which means your activity will be notified when the child activity is complete. In the second scenario, the launched activity is more a peer of your activity, so you probably want to launch the child just as a regular activity. Your activity will not be informed when the child is done, but, then again, your activity really doesn’t need to know. Start ’Em Up The two pieces for starting an activity are an intent and your choice of how to start it up. Make an Intent As discussed in the previous chapter, intents encapsulate a request, made to Android, for some activity or other intent receiver to do something. If the activity you intend to launch is one of your own, you may find it simplest to create an explicit intent, naming the component you wish to launch. For example, from within your activity, you could create an intent like this: new Intent(this, HelpActivity.class); This stipulates that you want to launch the HelpActivity. This activity would need to be named in your AndroidManifest.xml file, though not necessarily with any intent filter, since you are trying to request it directly. Or you could put together an intent for some Uri, requesting a particular action: Uri uri=Uri.parse("geo:"+lat.toString()+","+lon.toString()); Intent i=new Intent(Intent.ACTION_VIEW, uri); Here, given that you have the latitude and longitude of some position (lat and lon, respectively) of type Double, you construct a geo scheme Uri and create an intent requesting to view this Uri (ACTION_VIEW). Make the Call Once you have your intent, you need to pass it to Android and get the child activity to launch. You have two choices: CHAPTER 18: Launching Activities and Subactivities 179  The simplest option is to call startActivity() with the Intent. This will cause Android to find the best-match activity and pass the intent to it for handling. Your activity will not be informed when the child activity is complete.  You can call startActivityForResult(), passing it the Intent and a number (unique to the calling activity). Android will find the best-match activity and pass the intent over to it. Your activity will be notified when the child activity is complete via the onActivityResult() callback. With startActivityForResult(), as noted, you can implement the onActivityResult() callback to be notified when the child activity has completed its work. The callback receives the unique number supplied to startActivityForResult(), so you can determine which child activity is the one that has completed. You also get the following:  A result code, from the child activity calling setResult(). Typically, this is RESULT_OK or RESULT_CANCELLED, though you can create your own return codes (pick a number starting with RESULT_FIRST_USER).  An optional String containing some result data, possibly a URL to some internal or external resource. For example, an ACTION_PICK intent typically returns the selected bit of content via this data string.  An optional Bundle containing additional information beyond the result code and data string. To demonstrate launching a peer activity, take a peek at the Activities/Launch sample application. The XML layout is fairly straightforward: two fields for the latitude and longitude, plus a button. <?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" > <TableLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:stretchColumns="1,2" > <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="2dip" android:paddingRight="4dip" android:text="Location:" /> <EditText android:id="@+id/lat" android:layout_width="fill_parent" android:layout_height="wrap_content" android:cursorVisible="true" android:editable="true" android:singleLine="true" CHAPTER 18: Launching Activities and Subactivities 180 android:layout_weight="1" /> <EditText android:id="@+id/lon" android:layout_width="fill_parent" android:layout_height="wrap_content" android:cursorVisible="true" android:editable="true" android:singleLine="true" android:layout_weight="1" /> </TableRow> </TableLayout> <Button android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Show Me!" /> </LinearLayout> The button’s OnClickListener simply takes the latitude and longitude, pours them into a geo scheme Uri, and then starts the activity. package com.commonsware.android.activities; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; public class LaunchDemo extends Activity { private EditText lat; private EditText lon; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); Button btn=(Button)findViewById(R.id.map); lat=(EditText)findViewById(R.id.lat); lon=(EditText)findViewById(R.id.lon); btn.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { String _lat=lat.getText().toString(); String _lon=lon.getText().toString(); Uri uri=Uri.parse("geo:"+_lat+","+_lon); startActivity(new Intent(Intent.ACTION_VIEW, uri)); } }); } } CHAPTER 18: Launching Activities and Subactivities 181 The activity is not much to look at, as you can see in Figure 18–1. Figure 18–1. The LaunchDemo sample application, with a location filled in If you fill in a location (e.g., 38.8891 latitude and -77.0492 longitude) and click the button, the resulting map is more interesting, as shown in Figure 18–2. Figure 18–2. The map launched by LaunchDemo, showing the Lincoln Memorial in Washington DC Note that this is the built-in Android map activity; we did not create our own activity to display this map. In Chapter 33, you will see how you can create maps in your own activities, in case you need greater control over how the map is displayed. CHAPTER 18: Launching Activities and Subactivities 182 NOTE: This sample application may not work on an Android 2.0 AVD in the emulator, as the AVD appears to lack the Maps application. Tabbed Browsing, Sort Of One of the main features of the modern desktop web browser is tabbed browsing, where a single browser window can show several pages split across a series of tabs. On a mobile device, this may not make a lot of sense, given that you lose screen real estate for the tabs themselves. In this book, however, we do not let little things like sensibility stop us, so let’s demonstrate a tabbed browser, using TabActivity and Intent objects. As you may recall from Chapter 9, a tab can have either a View or an Activity as its contents. If you want to use an Activity as the content of a tab, you provide an Intent that will launch the desired Activity; Android’s tab-management framework will then pour the Activity’s UI into the tab. Your natural instinct might be to use an http: Uri the way we used a geo: Uri in the previous example: Intent i=new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse("http://commonsware.com")); That way, you could use the built-in browser application and get all of the features that it offers. Alas, this does not work. You cannot host other applications’ activities in your tabs; only your own activities are allowed, for security reasons. So, we dust off our WebView demos from Chapter 13 and use those instead, repackaged as Activities/IntentTab. Here is the source to the main activity, the one hosting the TabView: public class IntentTabDemo extends TabActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TabHost host=getTabHost(); host.addTab(host.newTabSpec("one") .setIndicator("CW") .setContent(new Intent(this, CWBrowser.class))); host.addTab(host.newTabSpec("two") .setIndicator("Android") .setContent(new Intent(this, AndroidBrowser.class))); } } CHAPTER 18: Launching Activities and Subactivities 183 As you can see, we are using TabActivity as the base class, and so we do not need our own layout XML, since TabActivity supplies it for us. All we do is get access to the TabHost and add two tabs, each specifying an Intent that directly refers to another class. In this case, our two tabs will host a CWBrowser and an AndroidBrowser, respectively. Those activities are simple modifications to the earlier browser demos: public class CWBrowser extends Activity { WebView browser; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); browser=new WebView(this); setContentView(browser); browser.loadUrl("http://commonsware.com"); } } public class AndroidBrowser extends Activity { WebView browser; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); browser=new WebView(this); setContentView(browser); browser.loadUrl("http://www.android.com/"); } } They simply load a different URL into the browser: the CommonsWare home page in one and the Android home page in the other. TIP: Using distinct subclasses for each targeted page is rather wasteful. Instead, you could package the URL to open as an “extra” in an Intent and used that Intent to spawn a general- purpose BrowserTab activity, which would read the URL out of the Intent extra and use that. The resulting UI shows what tabbed browsing could look like on Android, as shown in Figures 18–3 and 18–4. CHAPTER 18: Launching Activities and Subactivities 184 Figure 18–3. The IntentTabDemo sample application, showing the first tab Figure 18–4. The IntentTabDemo sample application, showing the second tab . com.commonsware.android.activities; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Button;. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent". android:id="@+id/lat" android:layout_width="fill_parent" android:layout_height="wrap_content" android:cursorVisible="true" android:editable="true" android:singleLine="true"

Ngày đăng: 01/07/2014, 21:20