標籤:android fragment sample 例子
Android在3.0之後引入了Fragment的概念,我猜測其想法可能只是想更好地相容大螢幕或者平板的開發,因為大螢幕可以展示更多的內容,而內容一多,邏輯有可能就亂,而利用Fragment,則可以將不同的邏輯封裝進不同的Fragment中,但是展現呢,還是在同一個Activity中,在同一個螢幕上顯示。而對於螢幕並不大的手機來說,如果一個頁面展示的東西並不多,那麼其實將邏輯直接寫在Activity,利用多個Activity實現多個頁面的展示,我覺得也是可以接受的,畢竟用Activity還是用Fragment只是一種手段的選擇,能夠協助我們解決問題就好,沒有什麼是一定的。
但是既然Google那麼推薦我們用Fragment,連ADT中預設的建立Activity都會幫我們把實現放到Fragment中,那說明在後面,某些我們不清楚的地方,fragment肯定是有著activity沒有的優勢的,即使Fragment在Fragment之間的跳轉和傳值是比較麻煩的,我們都要學習一下怎麼使用Fragment。
今天這篇博文我們就來學習一下如何使用Fragment,並且直接在Fragment中觸發跳到另一個Fragment中。
1)定義一個Activity:activity_main.xml,內容很簡單,就是放置一個FrameLayout作為Container,如下:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.lms.fmdemo.MainActivity" tools:ignore="MergeRootFrame" />
2)定義三個Fragment的布局,如下:
2.1)fragment_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.lms.fmdemo.MainActivity$PlaceholderFragment" > <Button android:id="@+id/btnMain" android:layout_width="200dp" android:layout_height="50dp" android:layout_centerInParent="true" android:text="@string/main_fragment" /></RelativeLayout>
2.2)fragment_sec.xml 和 fragment_third.xml都跟fragment_main.xml類似,中間只放置一個按鈕。
這三個布局呢,當我們點擊Main的按鈕時,會跳到第二個Fragment,當我們點擊第二個Fragment中的按鈕時,就會跳到第三個Fragment,簡單實在。
3)建立三個Fragment執行個體,分別對應上面的三個布局,我們就拿第一個MainFragment來講解一下。
public class MainFragment extends Fragment implements OnClickListener{public interface MainFragmentClickListener{public void onMainButtonClicked();}private MainFragmentClickListener mActionTaker;public MainFragment() {}public void onAttach(Activity activity) {super.onAttach(activity);try {mActionTaker = (MainFragmentClickListener) activity;} catch (Exception e) {throw new RuntimeException(activity.toString() + " must implements MainFragmentClickListener Inerface");}}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View rootView = inflater.inflate(R.layout.fragment_main, container,false);Button btnMain = (Button) rootView.findViewById(R.id.btnMain);btnMain.setOnClickListener(this);return rootView;}@Overridepublic void onClick(View arg0) {mActionTaker.onMainButtonClicked();}}
3.1)建立的MainFragment要繼承於Fragment(注意,為了相容2.x的系統,這裡要使用support.v4包裡面的fragment類)。
3.2)定義一個回調介面,且這個介面必須要被包含此Fragment的Activity實現。Fragment之間是沒有辦法互相跳轉的,它們之間所謂的跳轉操作其實是由FragmentManager在主Activity中的添加替換刪除等操作組成的,也就是說,其實它們是被操作的,所以如果想在Fragment中觸發跳轉的操作的話,就必須將這個跳轉事件讓Activity知道,由Activity來操作。
3.3)在onAttach方法中,將Activity給強制轉換成第二步實現的介面,如果有異常,說明Activity沒有實現此介面,則會報錯。這一步,只是為了確保主Activity有實現這個介面,當然,也可以在這裡擷取一個Activity對象,供後面利用。
3.4)定義onCreateView方法,在onCreateView方法中,實始化當前Fragment的布局,並為不同的控制項設定不同的響應函數等之類。在這個例子中,我們只是簡單設定了一個按鈕。
3.5)在按鈕的響應函數中,由於只有一個按鈕有這個響應函數,所以在這裡並不判斷控制項的id,直接調用第二步定義介面的回呼函數,即Activity會處理這個響應函數。
一個Fragment主要的實現架構基本上就是這樣,在本頁面上的邏輯,基本上就跟普通的Activity一樣,可以直接處理。只有當涉及到其他的頁面(Fragment)的時候,我們才需要利用回調介面,來實現過渡。有可能是本個Fragment會被替換成另外一個Fragment,而這隻能由Activity做,沒辦法自殺的。
4)在Activity中載入我們定義的Fragment,並且處理對應Fragment的介面函數,如下:
public class MainActivity extends ActionBarActivity implements MainFragmentClickListener, SecondFragmentClickListener{private FragmentManager fragmentManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);fragmentManager = getSupportFragmentManager();if (savedInstanceState == null) {fragmentManager.beginTransaction().add(R.id.container, new MainFragment()).commit();}}...@Overridepublic void onMainButtonClicked() {fragmentManager.beginTransaction().replace(R.id.container, new SecondFragment()).addToBackStack(null).commit();}@Overridepublic void onSecondButtonClicked() {fragmentManager.beginTransaction().replace(R.id.container, new ThirdFragment()).addToBackStack(null).commit();}
在上面的Activity中,實現了MainFragmentClickListener和SecondFragmentClickListener,分別是兩個Fragment中定義的介面,而在其對應的實現方法,我們只是簡單地將一個新的Fragment放到Container中去,
如 onMainButtonClicked,在此方法,我們利用FragmentManager.beginTransaction方法獲得Transaction對象,然後調用其replace方法,將SecondFragment替換掉原來在onCreate時載入的MainFragment對象,最後 commit。
綜合來看,Activity的邏輯是最簡單的,可以說,它沒有什麼業務相關的邏輯,所有業務相關的邏輯應該都在對應的Fragment中實現,而Activity只是負責不同的Fragment之間的切換。
到這裡,在Activity中利用Fragment來實現App頁面之間跳轉就基本實現了。而這跟普通的app,利用Activity來實現頁面跳轉,其實架構基本上是一樣的,下面就是其運行效果:
結束。原始碼下載!