Android Fragment使用全解析

vn880254 8年前發布 | 6K 次閱讀 安卓開發 Android開發 移動開發

Fragment的使用可謂是老生常談了~~~

1、概述

自API 11引入Fragment之后,Fragment可謂風靡一時,現在大部分項目都或多或少的用到了Fragment,其更輕量級,更加適用屏幕,更加方便UI設計等優勢。說了這么多什么是Fragment呢?

Fragment:碎片,碎片是一個應用程序的用戶界面和行為能夠被放置在一個活動上。在其核心,它代表了一個特定的操作或界面,運行在一個更大的活動上。代表界面是因為可作為View在布局中進行使用,代表特定操作是因為包含生命周期可進行邏輯操作。 簡言之,Fragment就是一個帶生命周期的組件。 (若有問題懇請指正!)

Fragment的特點:

  • 生命周期必須依賴于Activity, 當Activity被銷毀,所有的碎片將被摧毀。(自己曾經踩坑)
  • 輕量級,輕量切換。
  • 方便處理平板、Phone的界面差異。

2、繼承結構和生命周期

繼承結構:

 

 

Fragment直接繼承Object,有四個直接子類,我個人對它的子類使用甚少。

生命周期:

 

 

Fragment的生命周期在圖上標注的很清楚了就不贅述了。該圖是很久之前收藏的,已忘記原出處,在此感謝原作者!

3、基本使用

1.靜態使用

靜態使用就是Fragment相當于控件一樣在布局中使用。

TestFragment.java 繼承Fragment重寫onCreateView方法

/**
 * Created by magic on 2016年9月27日.
 */
public class TestFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container);
        ImageView img=(ImageView)view.findViewById(R.id.img);
        img.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity(),"這是一個fragment", Toast.LENGTH_SHORT).show();
            }
        });
        return view;
    }

}

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

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/img" />

</RelativeLayout>

MainActivity.java 里面其實什么也沒干。

/**
 * Created by magic on 2016年9月27日.
 */
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

}

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

    <fragment
        android:id="@+id/id_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.magic.test_fragment.TestFragment" />

</RelativeLayout>

使用 fragment 標簽添加碎片,通過class指定碎片的完整類名。

運行效果:

 

 

2.動態使用

動態使用就是向Fragment布局容器中動態添加、替換、移除、隱藏、顯示Fragment。

CommonFragment.java

/**
 * Created by magic on 2016年9月27日.通用Fragment
 */
@SuppressLint("ValidFragment") 
public class CommonFragment extends Fragment {

    String desc;

    public CommonFragment(String desc) {
        super();
        this.desc = desc;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_common, container, false);
        TextView tev = (TextView) view.findViewById(R.id.tev);
        System.out.println(desc);
        tev.setText(desc);
        return view;
    }

}

通過構造方法傳遞數據的形式向TextView上設置內容。

fragment_common.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tev"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textColor="@color/mainOrange" />

</LinearLayout>

MainActivity.java

/**
 * Created by magic on 2016年9月27日.底部tab+fragment
 */
public class MainActivity extends Activity implements OnClickListener {

    TextView tev_tab1, tev_tab2, tev_tab3, tev_tab4;

    // fragment事務類
    FragmentTransaction ft;
    // fragment
    CommonFragment tabFragment1, tabFragment2, tabFragment3, tabFragment4;

    @SuppressLint("CommitTransaction")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        initView();

        ft = getFragmentManager().beginTransaction();

        tabFragment1 = new CommonFragment("Tab1");
        // 替換
        ft.replace(R.id.container, tabFragment1);
        // 提交
        ft.commit();
    }

    // 初始化控件
    private void initView() {
        tev_tab1 = (TextView) findViewById(R.id.tev_tab1);
        tev_tab2 = (TextView) findViewById(R.id.tev_tab2);
        tev_tab3 = (TextView) findViewById(R.id.tev_tab3);
        tev_tab4 = (TextView) findViewById(R.id.tev_tab4);

        tev_tab1.setOnClickListener(this);
        tev_tab2.setOnClickListener(this);
        tev_tab3.setOnClickListener(this);
        tev_tab4.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        FragmentTransaction ft = getFragmentManager().beginTransaction();

        switch (v.getId()) {
        case R.id.tev_tab1:
            ft.replace(R.id.container, tabFragment1);
            break;
        case R.id.tev_tab2:
            if (tabFragment2 == null) {
                tabFragment2 = new CommonFragment("Tab2");
            }
            ft.replace(R.id.container, tabFragment2);
            break;
        case R.id.tev_tab3:
            if (tabFragment3 == null) {
                tabFragment3 = new CommonFragment("Tab3");
            }
            ft.replace(R.id.container, tabFragment3);
            break;
        case R.id.tev_tab4:
            if (tabFragment4 == null) {
                tabFragment4 = new CommonFragment("Tab4");
            }
            ft.replace(R.id.container, tabFragment4);
            break;
        }
        // 提交
        ft.commit();
    }

}

activity_main2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/mainTextBlack"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/tev_tab1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="Tab1"
            android:textColor="@color/white" />

        <TextView
            android:id="@+id/tev_tab2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="Tab2"
            android:textColor="@color/white" />

        <TextView
            android:id="@+id/tev_tab3"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="Tab3"
            android:textColor="@color/white" />

        <TextView
            android:id="@+id/tev_tab4"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="Tab4"
            android:textColor="@color/white" />
    </LinearLayout>

</LinearLayout>

通過 FrameLayout 標簽創建Fragment的容器,底部四個Tab添加監聽事件用于動態更換FrameLayout容器中的Fragment。

運行效果:

 

 

4、相關類及主要方法

FragmentManager碎片管理器,抽象類,具體實現在 Android -support-v4.jar中的FragmentManagerImpl類中。

// 獲取FragmentManager對象
        FragmentManager manager = getFragmentManager();

FragmentTransaction碎片事務類,抽象類,具體實現在BackStackRecord類中。添加、刪除、替換等操作其實最終的實現還是在FragmentManagerImpl類中。

// 獲取FragmentTransaction對象
        FragmentTransaction transaction = manager.beginTransaction();

        // 添加fragment
        transaction.add();
        transaction.add(containerViewId, fragment, tag);
        // 將被添加到容器的現有fragment替換
        transaction.replace();
        // 刪除一個現有的fragment
        transaction.remove();

        // 保存當前fragment數據,避免視圖重繪
        transaction.hide();
        // 顯示以前隱藏的fragment
        transaction.show();
        // 這兩個方法會觸發fragment中的onHiddenChanged(boolean hidden)回調

        // 顯示之前數據 實例不會被銷毀,但是視圖層次依然會被銷毀,即會調用onDestoryView和onCreateView
        transaction.addToBackStack(null);
        // 事務提交
        transaction.commit();

Fragment 碎片類

Fragment fragment = new Fragment();

        // 返回此fragment當前關聯的Activity
        fragment.getActivity();
        // 設置數據
        fragment.setArguments(new Bundle());
        // 獲取數據
        fragment.getArguments();
        // 返回與該fragment作用的FragmentManager
        fragment.getFragmentManager();
        // 獲取標簽名
        fragment.getTag();

        // 當隱藏狀態改變的時候回調
        // onHiddenChanged(true);

有興趣大家可以去Read The Fucking Source,反正我看的比較頭大…….

 

來自:http://www.androidchina.net/5726.html

 

 本文由用戶 vn880254 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!