新技术论坛
搜索
查看: 1032|回复: 0
打印 上一主题 下一主题

[Android] Android Fragment使用全解析

[复制链接]
  • TA的每日心情
    开心
    2016-12-9 18:18
  • 签到天数: 85 天

    连续签到: 1 天

    [LV.6]常住居民II

    扫一扫,手机访问本帖
    楼主
    跳转到指定楼层
    发表于 2016-12-5 00:44:35 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

    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"
    •     androidrientation="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"
    •     androidrientation="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"
    •         androidrientation="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,反正我看的比较头大…….


    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    手机版|Archiver|开发者俱乐部 ( ICP/ISP证:辽B-2-4-20110106号 IDC证:辽B-1-2-20070003号 )

    GMT+8, 2024-12-24 02:58 , Processed in 0.198709 second(s), 22 queries .

    X+ Open Developer Network (xodn.com)

    © 2009-2017 沈阳讯网网络科技有限公司

    快速回复 返回顶部 返回列表