Android的每一個畫面都是一個Activity元件, 多個畫面就需要有多個Activity元件.
主畫面設定檔
應用程式啟動後, 第一個出現的畫面叫主畫面. 在AndroidManifest.xml 設定檔的架構如下
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<category android:name=”android.intent.category.LAUNCHER” /> 為應用程式啟動後第一個執行的畫面, 此設定固定不變
切換新增Activity元件
假如今天有A這個主畫面, 然後想到切換到B的畫面, 就需要使用Intent的方式來執成. 底下的說明步驟實際演練一次.
1. 開啟res/layout/activtiy_main.xml, 改為LinearLayout, 放置一個EditText : editTel, 及一顆按鈕 : btnFirst, Text改為 “切換”
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.asuscomm.mahaljsp.ch11_01_newactivity.MainActivity"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:id="@+id/editTel"
android:inputType="phone" />
<Button
android:text="切換"
android:onClick="btnFirst_click"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnFirst"/>
</LinearLayout>
2. 在專案按右鍵/new/Activity/Empty Activity, Activity name : SecondActivity, Layout name : activity_second.xml
3. 開啟activity_second.xml, Layout改為LinearLayout, 然後放置一顆按鈕, id為btnSecond, Text改為”返回”
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_second" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.asuscomm.mahaljsp.ch11_01_newactivity.SecondActivity" android:orientation="vertical"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:text="電話 : " android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textView1"/> <TextView android:text="TextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/txtTel"/> </LinearLayout> <Button android:text="返回" android:onClick="btnSecond_click" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/btnSecond" /> </LinearLayout>
4. 開啟AndroidManifest.xml設定檔, 將設定檔改為如下
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SecondActivity" android:label="第二個畫面"> </activity> </application>
5. MainActivity.java如下
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void btnFirst_click(View view){ Intent intent=new Intent(this, SecondActivity.class); startActivity(intent); } }
AndroidManifest.xml設定檔
每新增一個Activity元件, 就需要在設定檔新增<activity>標簽. <activity>標簽常用設定如下
android:name : 元件類別名稱
android:screenOrientation : 有portrait, landscape, locked
<activity android:name=".SecondActivity" android:screenOrientation="landscape" android:label="第二個畫面"> </activity>
Intent
Intent類別用來啟動另一個Activity元件, Service元件, 或是發送廣播. 其建構子有三種
Intent(Context, Class) : 由目前的Context轉換到Class
Intent(String) : 轉換到action
Intent() : 調用setAction()後再進行轉換
class
如上例, 直接new 出Intent, 指定由 this轉換到SecondActivity.class, 再用startActivity(intent)開始進行切換
action
在<activity>標簽中加入如下
<activity android:name=".SecondActivity" android:screenOrientation="landscape" android:label="第二個畫面"> <intent-filter> <action android:name="com.asuscomm.mahaljsp.IntentTest.Second" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
<action android:name>請輸入獨一無二之名稱, 而<category android:name=”android.intent.category.DEFAULT” />則為一般的Action.
若為 category.LAUNCHER, 則表示是第一個主畫面.
而在Java程式中使用如下方式啟動
public void btnFirst_click(View view){ Intent intent=new Intent("com.asuscomm.mahaljsp.IntentTest.Second"); startActivity(intent); }
傳送與接收資料
傳送資料
當由主畫面A切換到B畫面時, 若要連同一些資料也傳送給B, 則可以把資料放入Intent中一起傳送. Intent類別提供 putExtra(字串, 資料)方法. 第二個參數可以是八大原生基本資料, 也可以是String, CharSequence. 另還有一個特殊的Bundle物件
public void btnFirst_click(View view){
Intent intent=new Intent("com.asuscomm.mahaljsp.IntentTest.Second");
intent.putExtra("Tel", editTel.getText().toString());
startActivity(intent);
}
Bundle
Bundle可以把不同的資料形態包在一起, 再使用Intent類別的putExtra(String, Bundle)傳送給啟動元件. 首先創造一個Bundle物件.
Bundle bundle=new Bundle();
再用bundle.putInt(String, int), bundle.putString(String, String)等方法將資料包入Bundle物件. 之後就可以使用Intent的putExtra(String, Bundle), 或putExtras(Bundle)傳送出去
public void btnFirst_click(View view){ Intent intent=new Intent("com.asuscomm.mahaljsp.IntentTest.Second"); Bundle bundle=new Bundle(); bundle.putInt("Age", 23); bundle.putString("Tel", editTel.getText().toString()); intent.putExtra("Info", bundle); startActivity(intent); }
接收資料
被呼叫端啟動後, 可先使用getIntent()取得傳送進來的Intent物件. 再由Intent的intent.getIntExtra(String, default), intent.getStringExtra(String)等方法取得資料.
如果傳送進來的是Bundle物件, 則可使用下列二種方式取得Bundle物件
Bundle bundle=intent.getExtras();
Bundle bundle=intent.getBundleExtra(String);
然後再由bundle.getString(), bundle.getInt()等方式取得資料
回傳
當由主畫面A切換到B畫面, 然後又要由B切回A時, 稱為回傳. 此時由A切到B需使用startActivityForResult(intent, requestCode)進行切換. 待B切回A時, 會執行A的
protected void onActivityResult(int requestCode, int resultCode, Intent data)方法
resultCode是指由B切回的狀況, 有Activity.RESULT_OK及Activity.RESULT_CANCELED二種. 請注意, 當使用者按back鍵切回A, 是屬於Activity.RESULT_CANCELED.
requestCode是由A切換到B, 再切回來A的識別碼, 可用此碼判斷是A的那一個按鈕動作的
接收端B接收Intent後, 若想傳回值給A, 則需使用原來的Intent物件, 置入資料後, 再使用setResult(resultCode, Intent)回傳, 最後再把B自己finish();
完整範例如下
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.asuscomm.mahaljsp.ch11_01_newactivity"> <application android:allowBackup="true" android:icon="@drawable/lpic" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:screenOrientation="locked" android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SecondActivity" android:label="請選擇行星"> <intent-filter> <action android:name="com.asuscomm.mahaljsp.IntentTest.Second" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> </manifest>
arrays.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="planet_array"> <item>Mercury</item> <item>Venus</item> <item>Earth</item> <item>Mars</item> <item>Jupiter</item> <item>Saturn</item> <item>Uranus</item> <item>Neptune</item> <item>Pluto</item> </string-array> </resources>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.asuscomm.mahaljsp.ch11_01_newactivity.MainActivity" android:orientation="vertical"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:text="1 " android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textView" android:textSize="20sp" /> <TextView android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" android:id="@+id/txt1"/> <ImageButton android:onClick="onClick" android:layout_width="80dp" android:layout_height="wrap_content" app:srcCompat="?android:attr/actionModeWebSearchDrawable" android:id="@+id/bt1"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:text="2 " android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:id="@+id/textView2"/> <TextView android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" android:id="@+id/txt2"/> <ImageButton android:onClick="onClick" android:layout_width="80dp" android:layout_height="wrap_content" app:srcCompat="?android:attr/actionModeWebSearchDrawable" android:id="@+id/bt2"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:text="3 " android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:id="@+id/textView3"/> <TextView android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" android:id="@+id/txt3"/> <ImageButton android:onClick="onClick" android:layout_width="80dp" android:layout_height="wrap_content" app:srcCompat="?android:attr/actionModeWebSearchDrawable" android:id="@+id/bt3"/> </LinearLayout> </LinearLayout>
activity_second.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_second" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.asuscomm.mahaljsp.ch11_01_newactivity.SecondActivity" android:orientation="vertical"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> </LinearLayout> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/listView" /> </LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity { TextView txt1, txt2, txt3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); processViews(); } public void processViews(){ txt1=(TextView)findViewById(R.id.txt1); txt2=(TextView)findViewById(R.id.txt2); txt3=(TextView)findViewById(R.id.txt3); } public void onClick(View view){ Intent intent=new Intent(this, SecondActivity.class); int requestCode=0; switch(view.getId()){ case R.id.bt1: requestCode=0; break; case R.id.bt2: requestCode=1; break; case R.id.bt3: requestCode=2; break; } startActivityForResult(intent, requestCode); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); String planet=data.getStringExtra("Planet"); if(resultCode== Activity.RESULT_OK){ switch(requestCode){ case 0: txt1.setText(planet); break; case 1: txt2.setText(planet); break; case 2: txt3.setText(planet); break; } } } }
SecondActivity.java
public class SecondActivity extends AppCompatActivity { ListView listView; Intent intent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); processViews(); processControllers(); } public void processViews(){ intent=getIntent(); listView=(ListView)findViewById(R.id.listView); } public void processControllers(){ listView.setAdapter(ArrayAdapter.createFromResource( this, R.array.planet_array, android.R.layout.simple_list_item_1)); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { String s=adapterView.getItemAtPosition(i).toString(); intent.putExtra("Planet", s); setResult(Activity.RESULT_OK, intent); SecondActivity.this.finish(); } }); } }
啟動系統內建Acitivty
Android系統內鍵了許多的Activity元件, 比如撥打電話, 傳送簡訊, web 搜尋, 地圖導覽. 所以在我們自己開發的應用程式中, 可以直接呼叫.
系統內建的Activity都有設定<action>標簽. 但action 名稱又過長, 所以Intent類別就定義了幾個長用的變數, 比如android.intent.action.DIAL, 可以直接使用Intent.ACTION_DIAL來呼叫.
當呼叫這些Activity元件時, 若需要傳入資料, 可先使用如 Uri uri=Uri.parse(“tel:0987454123”)的格式, 利用parse()的方法將字串轉成Uri物件, 然後再用Intent的setData(Uri)將資料傳入
打電話
打電話的Action有ACTION_DIAL : 準備打電話, aCTION_CALL : 立即打電話, 程式碼如下
Intent intent=new Intent(); intent.setAction(Intent.ACTION_DIAL); Uri uri=Uri.parse("tel:0987454123"); intent.setData(uri); startActivity(intent);
簡訊
Intent intent=new Intent(Intent.ACTION_SENDTO); Uri uri=Uri.parse("smsto:0987454123"); intent.setData(uri); intent.putExtra("sms_body", "測試簡訊傳遞"); startActivity(intent);
電子郵件
Intent intent=new Intent(Intent.ACTION_SEND);
intent.setType("plain/text");
intent.putExtra(Intent.EXTRA_EMAIL, "mahaljsp@gmail.com");
intent.putExtra(Intent.EXTRA_SUBJECT,"eMail測試");
intent.putExtra(Intent.EXTRA_TEXT, "這是郵件的內容");
startActivity(Intent.createChooser(intent, "Send EMail")); //會彈出要使用那一支應用程式
網頁搜尋
Intent intent=new Intent(Intent.ACTION_WEB_SEARCH); intent.putExtra(SearchManager.QUERY, "mahaljsp"); startActivity(intent);
網頁瀏覽
Intent intent=new Intent(Intent.ACTION_VIEW); Uri uri=Uri.parse(""); intent.setData(uri); startActivity(intent);
顯示地圖
Intent intent=new Intent(Intent.ACTION_VIEW); String point="24.06,120.5232"; String zoom="16"; Uri uri=Uri.parse("geo:"+point+"?z="+zoom); intent.setData(uri); startActivity(intent);
地圖導航
Intent intent=new Intent(Intent.ACTION_VIEW); String from="24.06,120.5232"; String to="24.0816363,120.5362556"; Uri uri=Uri.parse("http://maps.google.com/maps?f=d&saddr="+from+"&daddr="+to); intent.setData(uri); startActivity(intent);
街景服務
Intent intent=new Intent(Intent.ACTION_VIEW); String point="24.0813997,120.5388488"; String direction="0"; String streetZoom="1.0"; String vertical="0"; String zoom="16"; Uri uri=Uri.parse("google.streetview:cbll="+point+"&cbp=1,"+direction+ ",,"+streetZoom+",0&mz="+zoom); intent.setData(uri); startActivity(intent);