android数据回传多个页面_Android Day06四大组件之Activity多页面跳转和数据传递
ToolBar中menu無法同時顯示圖標和文字問題的解決方法
Toolbar添加返回按鈕
ToolBar與ActionBar
1.什么是Activity
官方文檔是這么說的:Anwhich
users can interact in order to do something, such as dial the phone, ????take a photo, send an email, or
view a map. Each activity is given a window in ????which to draw its user interface. The window
typically fills the screen, but may be ????smaller than the screen and float on top of other
windows.
大致意思是說:Activity是一個應用程序組件,給用戶提供一個屏幕讓用戶可以與之交互做一些事
情。
2.Activity的生命周期
下面這張圖是官方文檔提供的Activity的生命周期的圖:
·onCreate 方法 ? ?當Activity啟動的是調用
·onDestroy方法 ? ?當Activity銷毀的時候調用
·onStart 方法 ? ?當Activity可見的時候調用
·onStop 方法 ? ? 當Activity
不可見的時候調用
·onResume 方法 ? ?當Activity上的按鈕 獲得焦點 可以被點擊的時候調用
·onPause?方法 ? ?當Activity 上的按鈕 失去焦點 按鈕不可以被點擊的時候調用
·onRestart 方法 ? 當界面被重新加載的時候調用
注意這個方法
■手機按鍵對應的Activity生命周期的回調方法
如果點擊BACK鍵,會調用Activity的onPause()、onStop()、onDestroy()方法,Activity
會注銷掉。
如果點擊HOME鍵,會調用Activity的onPause()、onStop()方法,但不會執行onDestroy() ? 方法,程序會運行在后臺。如果應用程序沒有被系統殺死,那么再點擊應用程序圖標會調用Activity的onRestart()、onStart()、OnResume()方法。
■特殊的回調方法組合
如果打開第一個Activity之后,不關閉它,開啟另外一個Activity(非透明的),會調用第一個Activity的onPause()、onStop()方法。
如果打開第一個Activity之后,不關閉它,開啟另外一個Activity(透明的),會調用第一個
Activity的onPause()方法,而不會去調用onStop()方法,因為第一個Activity還是可見的。如果關
閉透明的Activity,第一個Activity只會回調onResume()方法。
■切屏對應的Activity生命周期的回調方法
手機在切屏的時候,會先銷毀,再創建.走onPause()、onStop()、onDestroy()方法,再走onCreate
()、onStart()、onResume()方法。這一過程就相當于關閉并重新進入應用一樣,那么如何防止手機
在切屏時生命周期發生改變呢?
第一種方式:把Activity頁面的朝向寫死,通過這個屬性
android:screenOrientation="portrait"portrait代表豎屏 ?landscape代表橫屏
朝向寫死,在手機上方向是不能改變的,但是在AVD上仍可以切屏,只是生命周期沒有變化。
第二種方式:android:configChanges="orientation|keyboardHidden|screenSize"
3.Activity的清單配置
如果想讓Activity成為應用程序的入口,需要將activity的意圖過濾器配置如下:
Android允許程序有多個activity作為應用程序的入口,只要activity配置了以上的意圖過濾器,就會在手機桌面上創建多個應用程序圖標,點擊圖標會進入對應的activity界面。
如果activity節點沒有設置自己的label和icon,會默認使用application節點的label和icon。
4.Activity的頁面跳轉及數據傳遞
注意的問題,序列化的類中還有自定義的類,則這個類也要序列化,否則會出錯.
■啟動Activity傳數據和取數據
本Activity:傳數據,通過Intent對象的setData()和putExtra()方法封裝數據至Intent對象。
被調用的的Activity:取數據,通過Activity類的getIntent()方法先得到開啟這個Activity的
Intent對象,也就是本Activity里傳數據用到的Intent對象,然后通過
Intent對象的getXxxExtra()方法得到數據。
■啟動Activity的2種方式
第一種:不需要被啟動的Activity返回數據startActivity(intent);
第二種:需要被啟動的Activity返回數據startActivityForResult(intent, int類型的請求碼);
對于第二種Activity的啟動方式,需要思考的兩個問題?
1)被調用的Activity怎么返回數據?
首先,調用者Activity啟動被調用的Activity的方式是startActivityForResult(intent,?int類型的請求碼);
其次,在被調用的Activity里面,創建Intent對象,將要返回的數據封裝進Intent對
象,調用Activity類的Intent data)方法返回Intent對象。
如://將數據返回
Intent?intent?=?new?Intent();
intent.putExtra("phone",?phone);
setResult(10,?intent);
2)調用者Activity怎么獲取被調用的Activity所返回的數據?
通過復寫Activity的onActivityResult方法可以得到其它的一個或多個Activity返
回的數據.
如:
上面的截圖是Android官方文檔的截圖,利用了雙重判斷確定是哪個對象返回的數據,這樣顯
得更加嚴密. 返回的數據就存儲在方法中的參數data中,調用Intent對象的方法取出即可.
5.應用1_短信大全
需求:將一些好的短信顯示到ListView上,點擊某一條短信,就跳到手機的短信發送頁面,并把
ListView選中條目的內容添加到短信發送頁面的短信內容中.
分析:這個需求首先涉及到ListView的使用,然后跳到手機短信發送頁面,涉及到隱式意圖啟動系
統應用,并且要將本應用的數據傳遞到系統應用里,涉及到頁面跳轉和數據傳遞.
效果圖:
假如我點擊了ListView短信列表的第2條短信,然后就跳轉到短信發送頁面
核心代碼:
public?void?onItemClick(AdapterView>?parent,?View?view,
int?position,?long?id)?{
//得到點擊的item對應的數據
String?msg?=?objects[position];
//利用隱式意圖,跳轉到短信發送頁面。
//怎么寫過濾條件,查源碼。。。。
/*?
*/
Intent?intent?=?new?Intent();
//設置意圖對象的過濾條件
intent.setAction("android.intent.action.SEND");
intent.addCategory("android.intent.category.DEFAULT");
intent.setType("text/plain");
//傳遞數據給×××
intent.putExtra("sms_body",?msg);
/*
*?不小心用了setDataAndType(Uri.parse(msg),"text/plain");結果×××的聯系人處是data,發送內容什么也沒有。
*?*/
startActivity(intent);
}
那么問題來了,上面意圖對象的過濾條件及傳遞數據格式我是怎么知道的呢?
1)先打開Logcat,然后打開手機短信發送頁面,會看到Locat上打印這樣一行信息(如果沒有
打印任何信息,先安裝一個自己的應用,然后重新打開系統的短信發送頁面。):
?????2)然后去系統應用源碼里找到短信發送應用Sms,在清單文件里找到ComposeMessageActivity
的配置
短信發送頁面有很多的過濾器,都是用于發現不同格式數據的(用mimetype屬性來約束),
我們這里就只需要文本類型的數據,就選擇mimetype為text/plain的進行過濾了。
知道了意圖對象的過濾器,那么就可以為意圖對象設置過濾信息
3)但是,怎么給intent傳遞數據呢?那么就得看短信發送頁面的Activity是如何獲取調用
它的Intent的數據的?
通過在ComposeMessageActivity.java里搜索getStringExtra可以得到×××是根據
sms_body鍵名來獲取短信內容的。
所以Intent在putExtra時采用的鍵名是“sms_body”。
6.應用2_×××
需求:做一個如下圖所示的×××,布局采用混合線性布局。
功能1:在主UI界面中點擊“添加聯系人”那個+號按鈕,就彈出一個窗體列出聯系人(是
模擬數據,學到內容提供者即可獲取手機真正的聯系人),選擇一個聯系人后關閉
選擇聯系人頁面,并將選擇的聯系人電話返回顯示到主UI界面的文本框中。
功能2:在主UI界面中點擊“插入模板”按鈕,就彈出一個窗體列出一些短信,選擇一條
短信后關閉短信大全頁面,將將選擇的短信返回顯示到主UI界面的短信內容文本框
分析:上面的需求,也涉及到頁面跳轉和數據傳遞,不同的是被調用的頁面在關閉的同時還要
向調用者(主UI界面)返回選擇的數據。那么,這個應用要求的技術有以下幾點:
1)主UI界面在啟動其它Activity的時候,應當使用startActivityForResult的方式,并
復寫Activity的onActivityResult方法。
2)兩個返回數據的ListView都要設置item點擊事件,在事件中返回數據并關閉頁面。
3)發送短信的功能
核心代碼:
1)短信模板頁面
因為ListView只需顯示單列數據,適配器就直接使用ArrayAdapter了。//模擬數據
final?String[]?objects?=?{短信內容,為節省空間就不寫了。};
//得到?listview
ListView?lv_templates?=?(ListView)?findViewById(R.id.lv_templates);
//綁定lv的適配器,用ArrayAdapter。
lv_templates.setAdapter(new?ArrayAdapter(this,?R.layout.item_activity_sms_template,?R.id.item,?objects));
//注冊lv的item點擊事件
//要實現的邏輯:獲取數據,返回數據,關閉當前activity
lv_templates.setOnItemClickListener(new?OnItemClickListener()?{
@Override
public?void?onItemClick(AdapterView>?parent,?View?view,
int?position,?long?id)?{
//得到數據
String?content?=?objects[position];
//通過intent返回數據
Intent?intent?=?new?Intent();
intent.putExtra("content",?content);
setResult(20,?intent);
//關閉當前activity
finish();
}
});
2)選擇聯系人頁面//模擬數據
final?List>?lists?=?new?ArrayList>?();
for(int?i?=?0?;?i?
{
Map?map?=?new?HashMap();
map.put("name","聯系人"?+?i);
map.put("phone",new?Random().nextInt(252523)+"");
lists.add(map);
}
//得到?listview
ListView?lv_contacts?=?(ListView)?findViewById(R.id.lv_contacts);
//綁定lv的適配器,用SimpleAdapter,可以添加多個textview。
lv_contacts.setAdapter(new?SimpleAdapter(this,?lists,?R.layout.item_activity_contacts,new?String[]{"name","phone"},?new?int[]?{R.id.tv_name,R.id.tv_phone}));
//注冊lv的item點擊事件
//要實現的邏輯:獲取數據,返回數據,關閉當前activity
lv_contacts.setOnItemClickListener(new?OnItemClickListener()?{
@Override
public?void?onItemClick(AdapterView>?parent,?View?view,
int?position,?long?id)?{
//拿到相應item的數據,通過lists集合,只要電話號碼。
String?phone?=?lists.get(position).get("phone");
//將數據返回
Intent?intent?=?new?Intent();
intent.putExtra("phone",?phone);
setResult(10,?intent);
//關閉當前activity
finish();
}
});
3)主UI頁面
★獲取模板頁面和聯系頁面數據并顯示protected?void?onActivityResult(int?requestCode,?int?resultCode,?Intent?data)?{
//通過resultCode來區別不同的activity返回的intent對象
if(resultCode?==?10)
{
et_name.setText(data.getStringExtra("phone"));
}
else?if?(resultCode?==?20){
et_content.setText(data.getStringExtra("content"));
}
}
★發送短信
通過SmsManager這個類,注意它的獲取方式是通過SmsManager.getDefault方法
與打電話不同,打電話是通過隱式意圖來調用的。
記得要在清單文件里加上權限:
public?void?send()
{
//TODO?短信發送
//得到聯系人和發送內容
String?name?=?et_name.getText().toString().trim();
String?content?=?et_content.getText().toString().trim();
//利用一個類SmsManager來發送短信注意不要用過時的SmsManager
SmsManager?smsManager?=?SmsManager.getDefault();
//短信內容過長,就得切割之后再一條條發送。
ArrayList?divideMessage?=?smsManager.divideMessage(content);
for(String?msg?:?divideMessage)
{
smsManager.sendTextMessage(name,?null,?msg,?null,?null);
}
}
7.Android中的任務棧棧 :先進后出
隊列 ?先進先出
任務棧 ?:是用來維護Activity的
,| Activity是用來維護用戶的操作體驗的
打開一Activity 叫
進棧
關閉一個Activity 出棧
我們用戶操作的Activity
永遠是棧頂的Activity
說我們應用程序退出了
實際上是任務棧清空了
一般情況下
一個應用程序對應一個任務棧
8.Android中4種啟動模式
1.android:launchMode="standard"(默認)
2.singletop 單一頂部模式 在activity的配置文件中設置android:launchMode="singleTop"
如果任務棧的棧頂存在這個要開啟的activity,不會重新的創建activity,而是復用已經存在
的activity。保證棧頂Activity如果存在,不會重復創建。
應用場景:瀏覽器的書簽
3. singetask 單一任務棧,在當前任務棧里面只能有一個實例存在
當開啟activity的時候,就去檢查在任務棧里面是否有實例已經存在,如果有實例存在就復用
這個已經存在的activity,并且把這個activity上面的所有的別的activity都清空,復用這個已經
存在的activity。保證整個任務棧里面一個Activity只有一個實例存在
應用場景:瀏覽器的activity
如果一個activity的創建需要占用大量的系統資源(cpu,內存)一般配置這個activity為
singletask的啟動模式。webkit內核
c代碼
4.singleInstance啟動模式非常特殊, activity會運行在自己的任務棧里面,并且這個任務棧里面
只有一個實例存在
如果你要保證一個activity在整個手機操作系統里面只有一個實例存在,使用singleInstance
應用場景: 來電頁面???有道詞典
和Activity相關的其它技術點:
1.當 Activity 以全屏模式運行時,如何允許 Android 系統狀態欄在頂層出現,而不迫使 Activity 重新布局讓
出空間?
8.Android中4種啟動模式
1.設置activity不可點擊this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
9.LoadManager
9.Android屏幕旋轉導致Activity重建的幾種解決辦法
總結
以上是生活随笔為你收集整理的android数据回传多个页面_Android Day06四大组件之Activity多页面跳转和数据传递的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot banner在线生
- 下一篇: android 输入模糊匹配_Andro