Ⅰ 繼承frament和activity的區別
一、為什麼要使用Fragment
1、當我們需要動態的多界面切換的時候,就需要將UI元素和Activity融合成一個模塊。在2.3中我們一般通過各種Activity中進行跳轉來實現多界面的跳轉和單個界面動態改變。在4.0或以上系統中就可以使用新的特性來方便的達到這個效果--Fragment類。Fragment類似一個嵌套Activity,可以定義自己的layout和自己的生命周期。
2、 多個Fragment可以放在一個Activity中(所以上面講到類似一個嵌套Activity),而這個類可以對這些Fragment進行配置以適應不同的屏幕尺寸(比如平板和手機)。
二、使用Fragment
1、Fragment 是 activity 的界面中的一部分或一種行為。可以把多個 Fragment 組合到一個 activity 中來創建一 個多面界面並且可以在多個 activity 中重用一個 Fragment。可以把 Fragment 認為模塊化的一段 activity,它具 有自己的生命周期,接收它自己的事件,並可以在 activity 運行時被添加或刪除。
2、Fragment 不能獨立存在,它必須嵌入到 activity 中,而且 Fragment 的生命周期直接受所在的 activity 的影 響。
3、當向 activity 中添加一個 Fragment 時,它須置於 ViewGroup 控制項中,並且需定義 Fragment 自己的界面。可 以在 layoutxml 文件中聲明 Fragment,元素為:<fragment>;也可以在代碼中創建 Fragment,然後把它加入到 ViewGroup 控制項中。然而,Fragment 不一定非要放在 activity 的界面中,它可以隱藏在後台為 actvitiy 工作。
三、 生命周期
通常, 應當至少實現如下的生命周期方法:
onCreate()
當創建fragment時, 系統調用該方法.
在實現代碼中,應當初始化想要在fragment中保持的必要組件, 當fragment被暫停或者停止後可以恢復.
onCreateView()
fragment第一次繪制它的用戶界面的時候, 系統會調用此方法. 為了繪制fragment的UI,此方法必須返回一個View, 這個view是你的fragment布局的根view. 如果fragment不提供UI, 可以返回null.
onPause()
用戶將要離開fragment時,系統調用這個方法作為第一個指示(然而它不總是意味著fragment將被銷毀.) 在當前用戶會話結束之前,通常應當在這里提交任何應該持久化的變化(因為用戶有可能不會返回).
大多數程序應最少對 fragment 實現這三個方法。當然還有其它幾個回調方法可應該按情況實現之。
下圖為 fragment 的生命周期(它所在的 activity 處於運行狀態)。
四、如何使用Fragment
1、添加一個用戶界面
fragment通常用來作為一個activity的用戶界面的一部分,並將它的layout提供給activity.為了給一個fragment提供一 個layout,你必須實現 onCreateView()回調方法, 當到了fragment繪制它自己的layout的時候,android系統調用它.你的此方法的實現代碼必須返回一個你的fragment的 layout的根view.
從onCreateView()返回的View, 也可以從一個layout的xml資源文件中讀取並生成. 為了幫助你這么做, onCreateView() 提供了一個LayoutInflater 對象.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frament_main, container, false);
return view;
}
PS
傳入onCreateView()的container參數是你的fragmentlayout將被插入的父ViewGroup(來自activity的layout) savedInstanceState 參數是一個Bundle, 如果fragment是被恢復的,它提供關於fragment的之前的實例的數據,
inflate() 方法有3個參數:
a、想要載入的layout的resource ID.
b、載入的layout的父ViewGroup.傳入container是很重要的, 目的是為了讓系統接受所要載入的layout的根view的layout參數,由它將掛靠的父view指定.
c、布爾值指示在載入期間, 展開的layout是否應當附著到ViewGroup (第二個參數).
2、將fragment添加到activity
通常地, fragment為宿主activity提供UI的一部分, 被作為activity的整個viewhierarchy的一部分被嵌入. 有2種方法你可以添加一個fragment到activity layout:
2.1、使用XML將Fragment添加到一個Activity中
在這種情況下,你可以像為View一樣, 為fragment指定layout屬性。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.example.news.ArticleListFragment"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.news.ArticleReaderFragment"
android:id="@+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
PS
1、<fragment> 中的 android:name屬性指定了在layout中實例化的Fragment類.
當系統創建這個activity layout時,它實例化每一個在layout中指定的fragment,並調用每一個上的onCreateView()方法,來獲取每一個 fragment的layout.系統將從fragment返回的 View直接插入到<fragment>元素所在的地方.
2、通過在xml中定義fragment的方式,我們不能在運行時移除fragment。如果我們想要通過切換fragments來跟用戶有更好的互動,那麼就需要在activity啟動的時候定義fragment了。
2.2、在運行時添加一個Fragment到Activity
上面一節的在activity的布局文件(layout xml)中添加Fragment的方法我們已經知道了。現在我們將學習另外一種方式,這種方式允許我們在運行時動態的顯示和隱藏fragment。為了達到在activity中動態管理Fragment,我們需要用到FragmentManager,並且通過它創建FragmentTransaction。
activity允許移除或者替換fragment需要有如下條件:
1、activity的onCreate()方法中添加初始化的fragment
2、fragment放置位置的布局中必須有一個視圖容器
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Activity中使用getSupportFragmentManager()獲取FragmentManager,之後調用beginTransaction去創建一個FragmentTransaction對象, 再調用add()方法即可添加一個fragment。 在activity中可以使用同一個FragmentTransaction對象去執行多個fragment事務,當做這樣操作時,必須調用commint()方法。 下面的代碼演示怎樣添加一個fragment到res/layout/news_articles.xml的layout:
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
if (findViewById(R.id.fragment_container) != null) {
if (savedInstanceState != null) {
return;
}
HeadlinesFragment firstFragment = new HeadlinesFragment();
firstFragment.setArguments(getIntent().getExtras());
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
}
}