[Android]使用fragment製造Tab效果

開發環境:Android Studio 0.8.2

分頁已經是大家最常用的功能之一了,之前一直都是使用已經被棄用的的TabHost,也該找時間來試試這個官方推薦的Fragment,這邊是使用 ActionBar.Tab 的方式來加入由fragment所生成的Tab,並且將其裝在framelayout中。

首先是 activity_my.xml 也就是我們的主畫面

<?xml version="1.0" encoding="utf-8"?>

<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" />

這邊就簡單放個FrameLayout就可以了,接著因為只是要示範Tab的效果,所以只做了一個分頁,只是切換後顯示的內容不同,所以我們來做一個分頁的內容 tab.xml 

<?xml version="1.0" encoding="utf-8"?>

<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" >

    <TextView

        android:id="@+id/tabtextview"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_centerVertical="true"

        />

</RelativeLayout>

接著來完成分頁所需要用到的Fragment類,程式的邏輯可放在這邊

package william.home.testfragment02;

import android.app.Fragment;

import android.os.Bundle;

import android.support.annotation.Nullable;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.TextView;

public class FragmentTab1 extends Fragment {

    @Nullable

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.tab, container, false);

        TextView textview = (TextView) view.findViewById(R.id.tabtextview);

        textview.setText(R.string.One);

        return view;

    }

}

這邊用到的總共有三個,FragmentTab1 / FragmentTab2 / FragmentTab3 ,差別只是在於設定的文字不同而已(1/2/3)。

由於我們這邊是使用ActionBar Tab 的方式,所以我們要準備好監聽事件(Listener),好讓程式知道我們在點選Tab的時候,必須做什麼樣的運作,這邊我們用 implement ActionBar.TabListener 這個介面來完成 MyTabListener.java

package william.home.testfragment02;

import android.app.ActionBar;

import android.app.Fragment;

/**

 * Created by Hsu on 2014/8/4.

 */

public class MyTabListener implements ActionBar.TabListener {

    Fragment fragment;

    public MyTabListener(Fragment fragment) {

        this.fragment = fragment;

    }

    @Override

    public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {

        fragmentTransaction.replace(R.id.fragment_container, fragment);

    }

    @Override

    public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {

        fragmentTransaction.remove(fragment);

    }

    @Override

    public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {

        // nothing done here

    }

}

最後,我們將主要程式 MyActivity.java 完成

package william.home.testfragment02;

import android.app.ActionBar;

import android.app.Activity;

import android.app.Fragment;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

public class MyActivity extends Activity {

    ActionBar.Tab tab1, tab2, tab3;

    Fragment fragmentTab1 = new FragmentTab1();

    Fragment fragmentTab2 = new FragmentTab2();

    Fragment fragmentTab3 = new FragmentTab3();

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_my);

        // 取得ActionBar的實體

        ActionBar actionBar = getActionBar();

        // 官方又棄用了,現在改推薦使用 common navigation patterns

        // http://developer.android.com/design/patterns/navigation.html

        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // 設定分頁頁籤

        tab1 = actionBar.newTab().setText("1");

        tab2 = actionBar.newTab().setText("2");

        tab3 = actionBar.newTab().setText("3");

        // 設定監聽器,藉由 construct 將我們設置的 fragment 注入

        tab1.setTabListener(new MyTabListener(fragmentTab1));

        tab2.setTabListener(new MyTabListener(fragmentTab2));

        tab3.setTabListener(new MyTabListener(fragmentTab3));

        // 將設定好的 Tab 加入 ActionBar 中

        actionBar.addTab(tab1);

        actionBar.addTab(tab2);

        actionBar.addTab(tab3);

    }

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.

        getMenuInflater().inflate(R.menu.my, menu);

        return true;

    }

    @Override

    public boolean onOptionsItemSelected(MenuItem item) {

        // Handle action bar item clicks here. The action bar will

        // automatically handle clicks on the Home/Up button, so long

        // as you specify a parent activity in AndroidManifest.xml.

        int id = item.getItemId();

        if (id == R.id.action_settings) {

            return true;

        }

        return super.onOptionsItemSelected(item);

    }

}

接下來就可以看看程式運作的結果囉。

整體建置流程:

(1) 規劃主畫面

(2) 規劃分頁畫面

(3) 編寫分頁邏輯

(4) 編寫分頁監聽器

(5) 編寫主畫面程式

demo程式(右鍵另開視窗下載)

同場加映,使用FragmentActivity完成Tab範例下載