編輯:關於Android編程
作者 : 韓曙亮
轉載請著名出處 : http://blog.csdn.net/shulianghan/article/details/38064191
本博客代碼地址 :
-- 單一 Fragment 示例 : https://github.com/han1202012/Octopus-Fragement.git
-- 可復用的 Fragment 示例 : https://github.com/han1202012/Octopus-Fragement_TwoModel.git
Fragement 與 Activity 生命周期關系 : Fragement 嵌入到 Activity 組件中才可以使用, 其生命周期與 Activity 生命周期相關.
-- stop 與 destroy 狀態 : Activity 暫停 或者 銷毀的時候, 其內部嵌入的所有的 Fragement 也會執行 暫停 或者 銷毀 操作;
-- 活動狀態 : 只有當 Activity 處於活動狀態的時候, 我們才能操作 Fragement;
Fragement 特征 :
-- Fragement 與 Activity 交互 : Fragement 調用 getActivity() 獲取其 所嵌入的 Activity, Activity 獲取 FragementManager 的findFragementById() 或 findFragementByTag() 獲取 Fragement;
-- Activity 增刪 Fragement : Activity 調用 Fragement 的 add(), remove(), replace() 等方法 添加 刪除 替換 Fragement;
-- Fragement 與 Activity 對應關系 : 一個 Activity 中可以嵌入多個 Fragement, 一個 Fragement 可以嵌入多個 Activity;
-- 生命周期受 Activity 影響 : Fragement 的生命周期 受 Activity 生命周期控制;
Fragement 作用 : Fragement 是為了 Android 中 平台電腦 UI 設計, 開發者不用設計 非常負責的 界面, 只需要設計好模塊, 對UI 組件進行 分組 和 模塊化的設計和開發, 簡化了 UI 組件;
Fragement 可復用性 : 同一個 app 應用, 可以在不同的 Activity 中加載同一個 Fragement;
Fragement 子類 :
-- DialogFragement : 對話框界面的 Fragement, 顯示一個浮動的對話框, 這個對話框可以方便的與 Activity 進行交互, Activity 可以管理這個 Fragment;
-- ListFragement : 列表界面的 Fragement, 顯示一個條目列表, 該列表可以設置一個適配器, 提供了許多管理 列表的函數;
-- PerformanceFragement : 選項設置界面的 Fragement, 該Fragment 創建 類似與 設置 應用程序時很管用;
-- WebViewFragement : WebView 界面的 Fragement;
onCreate() :
onCreate(Bundle savedInstanceState)
-- 回調時機 : 在創建 Fragement 的時候回調;
-- 參數解析 : Bundle savedInstance, 用於保存 Fragment 參數, Fragement 也可以 重寫 onSaveInstanceState(Bundle outState) 方法, 保存Fragement狀態;
-- 執行的動作 : 獲取 Frgement 顯示的內容, 以及啟動Fragment 傳入的參數, 調用 getArguments() 獲取鍵值對;
onCreateView() :
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
-- 回調時機 : Fragement 繪制界面組件 的時候回調, 該方法返回 View, 這個View就是 Fragement 本身;
-- 參數解析 : inflater 布局加載器, 是上下文傳入, 不用自己創建; container 加載組件的父容器;
-- 執行的操作 : 使用 inflate 布局加載器 加載布局文件, 並未組件設置顯示的值;
onPause() :
-- 回調時機 : Fragement 暫停的時候, 即進入後台的時候 回調;
Fragment 創建 :
-- 參數准備 : 創建一個 Bundle 對象, 並向其中設置參數 :
Bundle bundle = new Bundle(); bundle.putString("key", "value");-- 創建 Fragment 對象 : 使用 new MyFragment() 創建對象, 並 調用 myFragment.setArguments(bundle) 方法傳入參數;
MyFragment myFragment = new MyFragment(); myFragment.setArguments(bundle);
Fragment嵌入Activity方式 : Fragment 添加到 Activity 中才能顯示, 以下是將 Fragment 嵌入 Activity 的方式;
-- 布局文件嵌入 : 在布局文件中 使用
-- 代碼方式嵌入 : 調用 FragmentTransaction 對象的 add() 方法向 Activity 中添加 Fragment;
Fragment 獲取 Activity : 調用 Fragment 對象的 getActivity()方法, 即可獲取 Fragment 嵌入的 Activity 對象;
Activity 獲取 Fragment :
-- Fragment 屬性 : 在布局文件中, 可以為
-- 獲取方法 : 調用 Activity 的 findFragmentById(int id) 或者 findFragmentByTag(String tag)方法;
Fragment 向 Activity 傳遞數據 : 將 Activity 當作接口子類對象, Fragment 中調用 Activity 中的接口方法;
-- Fragment 定義接口 : 在 Fragment 內部定義一個 Callback 接口;
-- Activity 實現該接口 : MyActivity extends Activity implement MyFragment.Callback;
-- Fragment 中獲取該接口對象 : 在Fragment 中定義一個 Callback 全局變量, 然後在 onAttach(Activity activity) 方法中, 將 activity 強轉為 Callback 對象;
-- 調用接口方法 : 上面獲取了 Callback 對象, 即Activity對象, 調用 Activity 中的 接口方法, 就能在 Fragment 中調用 Activity 對應的方法了;
Activity 向 Fragment 傳遞數據 :
-- 創建 Bundle 數據包 : 創建一個 Bundle 對象, 把要存放的鍵值對 放到這個對象中;
-- 設置 Bundle 對象給 Fragment : 調用 Fragment 對象的 setArguments(Bundle bundle) 方法, 將 Bundle 對象設置給 Fragment;
FragmentManager 功能 : FragmentManager 對象 可以通過 activity.getFragmentManager()獲取;
-- 獲取指定 Fragment : 通過 findFragmentById() 或者 findFragmentByTag() 方法獲取指定 Fragment;
-- 彈出棧 : 通過調用 popBackStack(), 將 Fragment 從後台的 棧 中彈出;
-- 監聽棧 : 通過調用 addOnBackStackChangeListener 注冊監聽器, 監聽 後台棧變化;
FragmentTransaction 對象獲取途徑 :
-- 獲取 FragmentManager 對象 : 調用 Activity 的 getFragmentManager() 獲取 FragmentManager 對象;
-- 獲取 FragmentTansaction 對象 : 調用 FragmentManager 對象的 beginTransaction() 方法獲取 FragmentTransaction 對象;
FragmentTransaction(Fragment 事務)作用 : 對 Fragement 進行 增, 刪 , 改 操作需要 FragmentTransaction 對象進行操作, 開啟 這個事務, 獲取 事務對象, 然後執行對 Fragment 的操作, 最後提交事務;
-- 開啟事務 : 調用 Fragement 對象的 beginTransaction() 方法可以獲取 FragementTransaction 對象;
-- 操作碎片 : FragmentTransaction 對象 中 包含了 add(), remove(), replace() 等方法;
-- 提交操作 : 當執行完 Fragement 的操作之後, 可以調用 FragementTransaction 對象的 commit() 方法提交修改;
addToBackStack()方法作用 : 該方法是 FragementTransaction 的方法, 在提交事務前調用該方法, 可以將 事務中執行的操作 添加到 back 棧中, 用戶按下 回退鍵, 修改過的 Fragement 會 回退到 事務執行之前的狀態;
活動狀態 : Fragment 處於前台, 可見, 可以獲取焦點;
暫停狀態 : Fragment 嵌入的Activity 也處於暫停狀態, 即 Fragment 處於後台, 可見, 失去焦點;
停止狀態 : Fragement 嵌入的 Activity 處於停止狀態, 不可見, 失去焦點;
銷毀狀態 : Fragement 所在的 Activity 被銷毀, 執行了 onDestroy() 方法, 此時 Fragement 被完全刪除;
紅色方法 與 Activity 相對應, 藍色方法 是 自身對應的方法, 棕色方法 單獨對應;<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD48cD48YnIgLz48L3A+PHA+PHN0cm9uZz5vbkF0dGFjaCgpPC9zdHJvbmc+IDogx7bI6ywgRnJhZ2VtZW50ILG7x7bI67W9IEFjdGl2aXR5IMqxu9i197jDt723qCwg1ru74bX308PSu7TOOzwvcD48cD48YnIgLz48L3A+PHA+PHN0cm9uZz5vbkNyZWF0ZSgpIDwvc3Ryb25nPjogtLS9qCwgRnJhZ2VtZW50ILS0vai1xMqxuvK72LX3uMO3vbeoLCDWu7vhu9i199K7tM47PC9wPjxwPjxiciAvPjwvcD48cD48c3Ryb25nPm9uQ3JlYXRlVmlldygpIDwvc3Ryb25nPjogu+bWxiwg1NogRnJhZ2VtZW50ILvm1sa1xMqxuvK72LX3uMO3vbeoLCC4w7e9t6i74be1u9ggu+bWxrXEIFZpZXcg1+m8/js8L3A+PHA+PGJyIC8+PC9wPjxwPjxzdHJvbmc+b25BY3Rpdml0eUNyZWF0ZWQoKTwvc3Ryb25nPiA6IL3nw+a0tL2oLCBGcmFnZW1lbnQgy/nHtsjrtcQgQWN0aXZpdHkgtLS9qM3qs8m72LX3uMO3vbeoOzwvcD48cD48YnIgLz48L3A+PHA+PHN0cm9uZz5vblN0YXJ0KCkgPC9zdHJvbmc+OiDG9LavLCBGcmFnZW1lbnQgxvS2r8qxu9i19ywgtMvKsUZyYWdlbWVudL/JvPs7PC9wPjxwPjxiciAvPjwvcD48cD48c3Ryb25nPm9uUmVzdW1lKCk8L3N0cm9uZz4gOiC8pLvuLCBGcmFnZW1lbnQgvfjI68ewzKgsIL/Ju/HIob25tePKsbyku+47PC9wPjxwPjxiciAvPjwvcD48cD48c3Ryb25nPm9uUGF1c2UoKTwvc3Ryb25nPiA6INTdzaMsIEZyYWdlbWVudCC9+MjruvPMqCwgsru/ybvxyKG9ubXjyrG8pLvuOzwvcD48cD48YnIgLz48L3A+PHA+PHN0cm9uZz5vblN0b3AoKTwvc3Ryb25nPiA6IM2j1rksIEZyYWdlbWVudCCyu7/JvPvKsbvYtfc7PC9wPjxwPjxiciAvPjwvcD48cD48c3Ryb25nPm9uRGVzdHJveVZpZXcoKTwvc3Ryb25nPiA6IM/6u9nX6bz+LCDP+rvZIEZyYWdlbWVudCC75tbGtcQgVmlldyDX6bz+yrG72LX3OzwvcD48cD48YnIgLz48L3A+PHA+PHN0cm9uZz5vbkRlc3Ryb3koKTwvc3Ryb25nPiA6IM/6u9ksIM/6u9kgRnJhZ2VtZW50ILvYtfc7PC9wPjxwPjxiciAvPjwvcD48cD48c3Ryb25nPm9uRGV0YWNoKCk8L3N0cm9uZz4gOiDSxrP9LCBGcmFnZW1lbnQgtNMgQWN0aXZpdHkg1tDSxrP9tcTKsbryu9i19zs8L3A+PHA+PGJyIC8+PC9wPjxwPjxiciAvPjwvcD48aDI+Ny4gtPrC68q+wP0gPC9oMj48cD48YnIgLz48L3A+PHA+PGJyIC8+PC9wPjxoMz4oMSkg0OjH87fWzvY8L2gzPjxwPjxiciAvPjwvcD48cD48c3Ryb25nPtfdz/LK1rv6xsHEuzwvc3Ryb25nPiA6IMG9uPa958PmLCDDv7j2vefD5ra809DSu7j2IEZyYWdlbWVudCwgINK7uPZGcmFnZW1lbnTP1Mq+0MLOxcHQse0sINK7uPZGcmFnZW1lbnQgz9TKvtDCzsXE2sjdOzwvcD48cD48c3Ryb25nPrrhz/LK1rv6xsHEuzwvc3Ryb25nPiA6INK7uPa958PmLCDBvbj2RnJhZ2VtZW50LCBGcmFnZW1lbnQgz9TKvsTayN3T68nPw+bP4M2sOzwvcD48cD48YnIgLz48L3A+PHA+PGJyIC8+PC9wPjxoMz4oMikg0MLOxbHqzOIgRnJhZ21lbnQ8L2gzPjxwPjxiciAvPjwvcD48cD48c3Ryb25nPrTmt8XQws7FserM4rXEIEZyYWdtZW50PC9zdHJvbmc+IDogTmV3c1RpdHRsZUZyYWdtZW50LmphdmE8L3A+PHA+PC9wPjxwcmUgY2xhc3M9"brush:java;">package cn.org.octopus;
import android.app.Activity;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
/**
* 內部類 :
* Callbacks接口
* Fragement中維護該接口子類對象
* 需要Activity實現該接口, 實現接口方法
* Activity 在onAttach()方法中傳入;
*
* 方法簡介 :
* 重寫生命周期的 11 個方法;
* onAttach() 方法中, 傳入所嵌入的Activity, 並判斷是否嵌入正確
* onCreate() 方法中, 創建 Fragement 中 ListView 的適配器, 並將適配器設置給 ListView
* onDetach() 方法中, 將 Callbacks 接口子類對象置空
*
* setChoiceMode() 設置ListView 的選擇模式
* onListItemClick() ListView 的點擊回調方法
* 注意 Android
*
*/
public class NewsTittleFragment extends ListFragment {
private Callbacks activityCallback; /* 從 onAttach()方法中傳入的 Callbacks 接口子類, 由 Activity 強制轉換而來 */
/** 定義回調接口
* 接口用法 :
* 1. 該 Fragement 所 Activity 實現該接口
* 2. 該 Fragement 中 維護一個 該接口子類, 即 Activity
* 3. 調用 Activity 接口子類的方法, 將數據傳遞給 Activity **/
public interface Callbacks{
public void onNewsSelect(int id);
}
/** Fragment 嵌入Activity */
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
System.out.println("onAttach");
if ( ! ( activity instanceof Callbacks))
System.out.println("Fragement in wrong Activity !");
/* 為Activity中定義的Callbacks接口子類對象賦值 */
activityCallback = (Callbacks) activity;
}
/** Fragement 創建
* 進行設置適配器操作 */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("onCreate");
/* 為 ListFragment 創建適配器
* 注意使用的是 Android 自帶的布局, 在 sdk\platforms\android-10\data\res\layout 目錄下
* */
ListAdapter adapter = new ArrayAdapter 存放新聞內容的 Fragment : NewsContentFragement.java; 新聞實體類 : 新聞數據 : 主界面代碼 : MainActivity.java 跟蹤的 Fragment 生命周期回調函數打印的結果 : . 引用 android.app.ListFragment, 不會出現錯誤, 而 引用 android.support.v4.app.ListFragment 類會出現如下錯誤; 錯誤 : ListView 適配器引用的 組件, 必須是已經加載過的, 通過 onCreate()中的 setContentView()方法加載, 或者通過 LayoutInflater 進行加載; 錯誤 : 需求 : 在手機豎屏的時候, 新聞列表 和 新聞內容 在兩個 Activity 中, 橫屏的時候, 在一個 Activity 中; 定義實際引用的資源 : 在 Java 代碼中引用資源的時候, 會到 values 中查詢, 是否有定義資源文件, 如果有, 優先按照該定義加載指定資源文件; -- 定義方式 : 下面的定義, 如果代碼中引用 R.layout.activity_main, 符合條件的話, 使用 R.layout.activity_main_land 布局文件; 判斷的依據 : 根據 兩個布局文件的差異, 任意查找一個組件, 或者定義一個 不占位置的組件, 來進行判定; activity_main.xml : activity_main_land.xml : activity_news_content.xml : 豎屏 : 橫屏 : 作者 : 韓曙亮 轉載請著名出處 : http://blog.csdn.net/shulianghan/article/details/38064191(3) 新聞內容的 Fragment
package cn.org.octopus;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class NewsContentFragement extends Fragment {
/* Bundle的key */
public static final String TAG_NEWS_ID = "cn.org.octopus.news.tittle";
private News news;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* 校驗 參數中是否包含 TAG_NEWS_ID 鍵值*/
boolean isIllegal = getArguments().containsKey(TAG_NEWS_ID);
if(isIllegal){
/* 如果包含 TAG_NEWS_ID 鍵值, 就會去鍵對應的 id */
int id = getArguments().getInt(TAG_NEWS_ID);
/* 從 NewsContent 單例對象中的 map 集合中獲取 news 對象 */
news = NewsContent.getInstance().news_map.get(id);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/* 加載布局文件 */
View rootView = inflater.inflate(R.layout.fragment_news_content, container, false);
/* 獲取新聞標題組件 */
TextView news_content_tittle = (TextView) rootView.findViewById(R.id.news_content_tittle);
/* 獲取新聞內容組件 */
TextView news_content_content = (TextView) rootView.findViewById(R.id.news_content_content);
if(null != news){
/* 設置新聞標題 */
news_content_tittle.setText(news.getTittle());
/* 設置新聞內容 */
news_content_content.setText(news.getContent());
}
return rootView;
}
}
(4) 新聞內容存儲相關代碼
package cn.org.octopus;
public class News {
private int id; //新聞序號
private String tittle; //新聞標題
private String content; //新聞內容
/** 構造方法 */
public News(int id, String tittle, String content) {
super();
this.id = id;
this.tittle = tittle;
this.content = content;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTittle() {
return tittle;
}
public void setTittle(String tittle) {
this.tittle = tittle;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
/* 這裡只返回標題, 是為了適配 ListFragement 時使用 */
@Override
public String toString() {
// return "News [id=" + id + ", tittle=" + tittle + ", content=" + content
// + "]";
return tittle;
}
}
package cn.org.octopus;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class NewsContent {
/* 單例模式
* 1. 私有 靜態 本類成員變量
* 2. 私有 構造 函數
* 3. 公共 靜態 函數, 檢查本類成員變量是否為null, 返回本類成員變量 */
private static NewsContent newsContent;
public List
(5) 主界面 Actiity 代碼
package cn.org.octopus;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import cn.org.octopus.NewsTittleFragment.Callbacks;
public class MainActivity extends Activity implements Callbacks {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* 加載布局文件, 這個布局文件中有一個 Fragment, 會自動加載該 Fragmet */
setContentView(R.layout.activity_main);
}
/**
* 實現的 Callbasks 接口的方法,
* 當 NewsTittleFragement 中的 ListView 被點擊的時候 回調
* */
@Override
public void onNewsSelect(int id) {
/* 創建 Bundle 對象, Activity 傳遞給 Fragment 的參數需要靠該對象進行傳遞 */
Bundle arguments = new Bundle();
/* 封裝數據到 Bundle 對象中, 注意提前定義好鍵值 */
arguments.putInt(NewsContentFragement.TAG_NEWS_ID, id);
/* 創建 Fragment 對象 */
NewsContentFragement fragement = new NewsContentFragement();
/* 將 Activity 要傳遞的數據 傳遞給 Fragment 對象 */
fragement.setArguments(arguments);
/* 獲取FragmentManager 對象 */
FragmentManager manager = getFragmentManager();
/* 開啟事務, 獲取事務 */
FragmentTransaction transaction = manager.beginTransaction();
/* 在事務中進行替換操作 */
transaction.replace(R.id.news_content, fragement);
/* 提交操作 */
transaction.commit();
}
}
(6) AndroidManifest.xml 配置文件
(7) 執行結果
I/System.out( 8604): onAttach
I/System.out( 8604): onCreate
I/System.out( 8604): onCreateView
I/System.out( 8604): onActivityCreated
I/System.out( 8604): onStart
I/System.out( 8604): onResume
I/System.out( 8604): onPause
I/System.out( 8604): onStop
I/System.out( 8604): onDestroyView
I/System.out( 8604): onDestroy
I/System.out( 8604): onDetach
界面執行結果 : 8. 出錯處理
(1) 引用 不用包中的 Fragment
08-06 22:17:12.537: E/AndroidRuntime(3751): FATAL EXCEPTION: main
08-06 22:17:12.537: E/AndroidRuntime(3751): java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.org.octopus/cn.org.octopus.MainActivity}: android.view.InflateException: Binary XML file line #11: Error inflating class fragment
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2255)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2309)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.ActivityThread.access$700(ActivityThread.java:157)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.os.Handler.dispatchMessage(Handler.java:99)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.os.Looper.loop(Looper.java:176)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.ActivityThread.main(ActivityThread.java:5319)
08-06 22:17:12.537: E/AndroidRuntime(3751): at java.lang.reflect.Method.invokeNative(Native Method)
08-06 22:17:12.537: E/AndroidRuntime(3751): at java.lang.reflect.Method.invoke(Method.java:511)
08-06 22:17:12.537: E/AndroidRuntime(3751): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
08-06 22:17:12.537: E/AndroidRuntime(3751): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
08-06 22:17:12.537: E/AndroidRuntime(3751): at dalvik.system.NativeStart.main(Native Method)
08-06 22:17:12.537: E/AndroidRuntime(3751): Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class fragment
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:710)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.view.LayoutInflater.rInflate(LayoutInflater.java:752)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.view.LayoutInflater.inflate(LayoutInflater.java:495)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
08-06 22:17:12.537: E/AndroidRuntime(3751): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:360)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.Activity.setContentView(Activity.java:1932)
08-06 22:17:12.537: E/AndroidRuntime(3751): at cn.org.octopus.MainActivity.onCreate(MainActivity.java:13)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.Activity.performCreate(Activity.java:5326)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2218)
08-06 22:17:12.537: E/AndroidRuntime(3751): ... 11 more
08-06 22:17:12.537: E/AndroidRuntime(3751): Caused by: android.app.Fragment$InstantiationException: Trying to instantiate a class cn.org.octopus.NewsTittleFragment that is not a Fragment
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.Fragment.instantiate(Fragment.java:584)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.Fragment.instantiate(Fragment.java:560)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.app.Activity.onCreateView(Activity.java:4908)
08-06 22:17:12.537: E/AndroidRuntime(3751): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:686)
08-06 22:17:12.537: E/AndroidRuntime(3751): ... 21 more
08-06 22:17:12.537: E/AndroidRuntime(3751): Caused by: java.lang.ClassCastException
08-06 22:17:12.537: E/AndroidRuntime(3751): ... 25 more
(2) ListView 適配器設置錯誤
08-06 22:39:22.139: W/dalvikvm(4413): threadid=1: thread exiting with uncaught exception (group=0x40dc0930)
08-06 22:39:22.139: E/AndroidRuntime(4413): FATAL EXCEPTION: main
08-06 22:39:22.139: E/AndroidRuntime(4413): android.content.res.Resources$NotFoundException: Resource ID #0x7f080001 type #0x12 is not valid
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.content.res.Resources.loadXmlResourceParser(Resources.java:3033)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.content.res.Resources.getLayout(Resources.java:1722)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.LayoutInflater.inflate(LayoutInflater.java:395)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:371)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.ArrayAdapter.getView(ArrayAdapter.java:362)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.AbsListView.obtainView(AbsListView.java:2603)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.ListView.makeAndAddView(ListView.java:1840)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.ListView.fillDown(ListView.java:681)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.ListView.fillFromTop(ListView.java:742)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.ListView.layoutChildren(ListView.java:1661)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.AbsListView.onLayout(AbsListView.java:2426)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.View.layout(View.java:14905)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewGroup.layout(ViewGroup.java:4601)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.View.layout(View.java:14905)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewGroup.layout(ViewGroup.java:4601)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.View.layout(View.java:14905)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewGroup.layout(ViewGroup.java:4601)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1021)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.View.layout(View.java:14905)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewGroup.layout(ViewGroup.java:4601)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.View.layout(View.java:14905)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewGroup.layout(ViewGroup.java:4601)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1694)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1552)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.LinearLayout.onLayout(LinearLayout.java:1465)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.View.layout(View.java:14905)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewGroup.layout(ViewGroup.java:4601)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.View.layout(View.java:14905)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewGroup.layout(ViewGroup.java:4601)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2213)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2027)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1237)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5162)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.Choreographer.doCallbacks(Choreographer.java:591)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.Choreographer.doFrame(Choreographer.java:561)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.os.Handler.handleCallback(Handler.java:725)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.os.Handler.dispatchMessage(Handler.java:92)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.os.Looper.loop(Looper.java:176)
08-06 22:39:22.139: E/AndroidRuntime(4413): at android.app.ActivityThread.main(ActivityThread.java:5319)
08-06 22:39:22.139: E/AndroidRuntime(4413): at java.lang.reflect.Method.invokeNative(Native Method)
08-06 22:39:22.139: E/AndroidRuntime(4413): at java.lang.reflect.Method.invoke(Method.java:511)
08-06 22:39:22.139: E/AndroidRuntime(4413): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
08-06 22:39:22.139: E/AndroidRuntime(4413): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
08-06 22:39:22.139: E/AndroidRuntime(4413): at dalvik.system.NativeStart.main(Native Method)
9. Fragement 復用問題
(1) 根據不同的環境加載不同的布局
-- 屬性說明 : type 資源的類型, name 資源名稱;(2) 判斷加載的布局文件
/* 查看加載的是哪個文件, 如果文件中包含 R.id.news_content_content 組件, 就說明現在是橫屏的 */
isLand = findViewById(R.id.news_content) != null;
(3) MainActivity 代碼差異
package cn.org.octopus;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import cn.org.octopus.NewsTittleFragment.Callbacks;
public class MainActivity extends Activity implements Callbacks {
private boolean isLand; /* 標識是否是橫屏 */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* 加載布局文件, 這個布局文件中有一個 Fragment, 會自動加載該 Fragmet */
setContentView(R.layout.activity_main);
/* 查看加載的是哪個文件, 如果文件中包含 R.id.news_content_content 組件, 就說明現在是橫屏的 */
isLand = findViewById(R.id.news_content) != null;
}
/**
* 實現的 Callbasks 接口的方法,
* 當 NewsTittleFragement 中的 ListView 被點擊的時候 回調
* */
@Override
public void onNewsSelect(int id) {
/* 如果是橫屏的情況, 兩個 Fragement 都在一個界面中 */
if(isLand){
/* 創建 Bundle 對象, Activity 傳遞給 Fragment 的參數需要靠該對象進行傳遞 */
Bundle arguments = new Bundle();
/* 封裝數據到 Bundle 對象中, 注意提前定義好鍵值 */
arguments.putInt(NewsContentFragement.TAG_NEWS_ID, id);
/* 創建 Fragment 對象 */
NewsContentFragement fragement = new NewsContentFragement();
/* 將 Activity 要傳遞的數據 傳遞給 Fragment 對象 */
fragement.setArguments(arguments);
/* 獲取FragmentManager 對象 */
FragmentManager manager = getFragmentManager();
/* 開啟事務, 獲取事務 */
FragmentTransaction transaction = manager.beginTransaction();
/* 在事務中進行替換操作 */
transaction.replace(R.id.news_content, fragement);
/* 提交操作 */
transaction.commit();
}else{ /* 豎屏的情況, 需要開啟 Activity */
System.out.println("isLand : " + isLand);
Intent intent = new Intent(getApplicationContext(), NewsContentActivity.class);
/* 通過 Intent 的 Bundle 對象傳遞參數 */
intent.putExtra(NewsContentFragement.TAG_NEWS_ID, id);
startActivity(intent);
}
}
}
(4) 新增了 NewsContentActivity
package cn.org.octopus;
import android.app.Activity;
import android.os.Bundle;
public class NewsContentActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* 設置布局文件 */
setContentView(R.layout.activity_news_content);
/* 創建 Fragement */
NewsContentFragement fragement = new NewsContentFragement();
/* 創建綁定的數據 */
Bundle bundle = new Bundle();
/* 從Activity 獲取 啟動該 Activity 的 Intent */
int id = getIntent().getIntExtra(NewsContentFragement.TAG_NEWS_ID, 0);
bundle.putInt(NewsContentFragement.TAG_NEWS_ID, id);
/* 設置數據給 Fragment */
fragement.setArguments(bundle);
/* 開啟事務 操作 Fragement 並提交 */
getFragmentManager().beginTransaction().add(R.id.news_content, fragement).commit();
}
}
(5) 新增 或 修改的布局文件
(6) 執行效果
先看一下singleInstance啟動模式的說明:只有一個實例,並且這個實例獨立運行在一個activity任務棧中,這個task只有這個實例,不允許有別的Activit
在之前app寫完測試的時候,跑完整個老化階段包括數據收發都沒問題,鍵入 adb shell top -m 5 發現我的 app pid 占用的 CPU是最多的,其實我想說
提示:因為該新聞app已經基本完成,所以下方代碼量較大,請謹慎!或者從 ViewPager和Fragment結合使用實現新聞類app(一)一步步向下看!經過幾天的努力,不
一、歷史回顧隨科技的迅速發展,當前已經全線進入4G時代,5G時代也即將開啟。Android版本迭代迅速,如今已是6.0的版本。時不時可以看到,手機危害了當前人群的生活,如