Android Fragment使用全解析
Fragment的使用可謂是老生常談了~~~
1、概述
自API 11引入Fragment之后,F(xiàn)ragment可謂風(fēng)靡一時,現(xiàn)在大部分項目都或多或少的用到了Fragment,其更輕量級,更加適用屏幕,更加方便UI設(shè)計等優(yōu)勢。說了這么多什么是Fragment呢?
Fragment:碎片,碎片是一個應(yīng)用程序的用戶界面和行為能夠被放置在一個活動上。在其核心,它代表了一個特定的操作或界面,運(yùn)行在一個更大的活動上。代表界面是因為可作為View在布局中進(jìn)行使用,代表特定操作是因為包含生命周期可進(jìn)行邏輯操作。簡言之,F(xiàn)ragment就是一個帶生命周期的組件。(若有問題懇請指正!)
Fragment的特點(diǎn):
- 生命周期必須依賴于Activity,當(dāng)Activity被銷毀,所有的碎片將被摧毀。(自己曾經(jīng)踩坑)
- 輕量級,輕量切換。
- 方便處理平板、Phone的界面差異。
2、繼承結(jié)構(gòu)和生命周期
繼承結(jié)構(gòu):
Fragment直接繼承Object,有四個直接子類,我個人對它的子類使用甚少。
生命周期:
Fragment的生命周期在圖上標(biāo)注的很清楚了就不贅述了。該圖是很久之前收藏的,已忘記原出處,在此感謝原作者!
3、基本使用
1).靜態(tài)使用
靜態(tài)使用就是Fragment相當(dāng)于控件一樣在布局中使用。
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 標(biāo)簽添加碎片,通過class指定碎片的完整類名。
運(yùn)行效果:
2).動態(tài)使用
動態(tài)使用就是向Fragment布局容器中動態(tài)添加、替換、移除、隱藏、顯示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;
- }
- }
通過構(gòu)造方法傳遞數(shù)據(jù)的形式向TextView上設(shè)置內(nèi)容。
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事務(wù)類
- 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 標(biāo)簽創(chuàng)建Fragment的容器,底部四個Tab添加監(jiān)聽事件用于動態(tài)更換FrameLayout容器中的Fragment。
運(yùn)行效果:
4、相關(guān)類及主要方法
FragmentManager碎片管理器,抽象類,具體實現(xiàn)在Android-support-v4.jar中的FragmentManagerImpl類中。
- // 獲取FragmentManager對象
- FragmentManager manager = getFragmentManager();
FragmentTransaction碎片事務(wù)類,抽象類,具體實現(xiàn)在BackStackRecord類中。添加、刪除、替換等操作其實最終的實現(xiàn)還是在FragmentManagerImpl類中。
- // 獲取FragmentTransaction對象
- FragmentTransaction transaction = manager.beginTransaction();
- // 添加fragment
- transaction.add();
- transaction.add(containerViewId, fragment, tag);
- // 將被添加到容器的現(xiàn)有fragment替換
- transaction.replace();
- // 刪除一個現(xiàn)有的fragment
- transaction.remove();
- // 保存當(dāng)前fragment數(shù)據(jù),避免視圖重繪
- transaction.hide();
- // 顯示以前隱藏的fragment
- transaction.show();
- // 這兩個方法會觸發(fā)fragment中的onHiddenChanged(boolean hidden)回調(diào)
- // 顯示之前數(shù)據(jù) 實例不會被銷毀,但是視圖層次依然會被銷毀,即會調(diào)用onDestoryView和onCreateView
- transaction.addToBackStack(null);
- // 事務(wù)提交
- transaction.commit();
Fragment 碎片類
- Fragment fragment = new Fragment();
- // 返回此fragment當(dāng)前關(guān)聯(lián)的Activity
- fragment.getActivity();
- // 設(shè)置數(shù)據(jù)
- fragment.setArguments(new Bundle());
- // 獲取數(shù)據(jù)
- fragment.getArguments();
- // 返回與該fragment作用的FragmentManager
- fragment.getFragmentManager();
- // 獲取標(biāo)簽名
- fragment.getTag();
- // 當(dāng)隱藏狀態(tài)改變的時候回調(diào)
- // onHiddenChanged(true);
有興趣大家可以去Read The Fucking Source,反正我看的比較頭大…….
5、其它
未完待續(xù)……