`
小骏向前冲
  • 浏览: 18290 次
社区版块
存档分类
最新评论

Fragment介绍(官方API文档)

阅读更多
Fragments
fragment代表了一种行为或是Activity中UI的一部分。你可以在一个activity中将几个fragment合并成一种组合UI,也可以在多个activity中重复利用同一个fragment。可以认为fragment是activity中的一个组件,它有自己的生命周期,有自己的输入事件,并且可以在activity运行期间添加或移除。
fragment必须存在于一个activity里面并且生命周期受所在的activity的生命周期影响。例如,当一个activity停止的时候,它里面所有的fragment也停止,当activity销毁时,它里面所有的fragment也同时销毁。然而,当一个activity活动时,你可以单独控制它里面的每一个fragment,比如添加或移除。当执行一个fragment事务的时候,你可以把它添加进它所在activity的back栈中——back栈中每一条记录就是一个操作过的fragment事务。这个back栈可以让用户通过按back按钮返回上一次的操作。
当在activity的layout中加入一个fragment,该fragment就存在于该activity视图结构的ViewGroup中而且该fragment也有了自己的视图布局,你可以通过在activity的layout文件中添加标签<fragment>来插入一个fragment或者通过在已存在的ViewGroup中添加代码。然而,不一定要在activity的layout文件中插入fragment标签,也可以创建一个无UI的fragment在后台为activity工作。

该文档详细介绍了怎样在应用中利用fragment,包括fragment被添加到activity的back栈后是怎么维护它的状态,怎么与activity还有activity中的其他fragment共享事件,怎么创建action bar等等。

设计哲学:
。。。。。

创建Fragment
要创建一个fragment,首先要创建一个继承Fragment的子类(或者是已存在的Fragment子类,比如ListFragment和DialogFragment)。该Fragment子类看起来和activity非常相似,它包括很多和activity类似的回调方法:onCreate(),onStart(),onPause(),onStop()等等。实际上,如果想把一个已存在的android应用转换成利用Fragment,只需要把activity里回调方法的代码分别移动到Fragment对应的的方法中。
通常我们至少需要实现下面生命周期中的方法:
onCreate()
该方法在系统建立fragment时被调用,可以在这里面初始化一些状态,以便从Stop或Pause状态中恢复。

OnCreateView()
当fragment首次绘制自己UI时调用。如果想要绘制自己的fragment UI,你必须在该方法中返回一个View,这个View作为fragment的根视图,如果该fragment不需要提供UI也可以返回null。
OnPause()
用户离开该fragment的时候会调用该方法,和activity的onPause()一样。

几乎所有应用都至少需要实现这三个方法,还有一些fragment生命周期中经常用到的回调方法,在后面的<处理Fragment生命周期>部分会详细介绍。

这里还有一些经常需要继承的fragment子类:
DialogFragment
显示一个悬浮的对话框。利用dialogfragment这个类来创建一个对话框是一种很不错的选择,因为你可以把它压入到所在activity管理的back栈里,可以让用户按back键回退这个对话框。
ListFragment
显示一个由adapter管理的list,跟listActivity类似,它提供了onListItemClick()等几个回调方法来管理该list。
PreferenceFragment
显示一个首选项列表,跟PreferenceActivity类似,这在为应用创建一个“设置”activity的时候很有用。

添加一个用户界面
要为fragment提供视图,首先必须实现onCreateView()回调方法,返回一个View作为根视图。
注意:如果你的fragment是ListFragment的子类,onCreateView()默认返回一个ListView,所以你不需要再重写onCreateView()。
想从onCreateView()中返回一个layout,可以加载定义在XML文件中的资源,onCreateView()提供了一个LayoutInfater对象:
public static class ExampleFragment extends Fragment {
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
								Bundle savedInstanceState) {
		return inflater.inflate(R.layout.example_fragment, container, false);
	}
}

参数container代表fragment被嵌入的父ViewGroup(可以理解为fragment所在的activity),参数 savedInstanceState和onCreate中的一样,是一个保存着状态的Bundle对象。

在activity中添加一个fragment
有两种把fragment添加到activity的方法:
1.在activity的layout文件中声明fragment
这种情况下,如果是一个view,你可以指定fragment的layout属性。
<?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="horizontal" >
    
    <fragment
        android:name="com.example.news.ArticleListFragment"
        android:id="@+id/list"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>  
    <FrameLayout
		android:name="com.example.news.ArticleReaderFragment"
        android:id="@+id/viewer"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2"/>
</LinearLayout>

android:name属性指定了实现该fragment的类。
当系统创建一个activity布局时,它会通过每一个fragment的onCreateView()方法获取每个fragment的布局,然后分别插入到activity的layout文件<fragment/>标签对应的位置中。

注意:每一个fragment都需要一个唯一的标志好让系统在activity重启的时候去恢复它(你也可以用该唯一标志去获取一个fragment来处理事务,例如移除)。有三种为fragment提供ID的方法:
给属性android:id提供一个唯一的ID
给属性android:tag提供一个唯一的字符串
如果上面两个属性都没有,则系统会用fragment的父容器的ID代替

2.或者,添加一个fragment到一个已有的ViewGroup中
在activity运行的任何时候,你都可以添加一个fragment到activity布局中,你只需要指定一个放置fragment的ViewGroup。
为了执行fragment事务,你需要运用FragmentTransaction。你可以像下面一样从activity中获取一个FragmentTransaction:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
接着你可以用add()方法指定要添加的fragment和要插入到的视图,像这样:
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

方法add()中第一个参数是fragment需要插入到的ViewGroup,是一个资源ID,第二个参数是需要添加的fragment。
最后,必须加上commint()方法让你的事务起效。
3.添加一个无UI的fragment
上面的例子展示了如何通过添加一个fragment为activity提供UI。然而,你也可以添加一个fragment不提供任何UI只是让它在后台运行。
为了添加一个无UI的fragment, 可以用add(Fragment,String)( 提供一个唯一的字符串“tag”, 而不是一个视图ID)方法。这样添加fragment是因为它与activity的布局并无联系, 不需要调用onCreateView(), 所以你不必实现onCreateView()。
不只是可以给无UI的fragment提供一个字符串tag,也可以为有UI的字符串提供字符串tag,但如果fragment没有UI,一个字符串的tag就是唯一的辨识方法了。如果你需要在稍后重新获得这个fragment,你需要用到方法findFragmentByTag()。
下面这个例子就展示了activity如何用无UI的fragment作为一个后台工作线程。
/** 
 * 这个例子展示了当activity因为某些原因(比如配置变化)重启的时候怎么运用Fragment把
 * 之前状态传递给activity,这比用API Activity.onRetainNonConfiguratinInstance()
 * 简单多了
 * This example shows how you can use a Fragment to easily propagate state
 * (such as threads) across activity instances when an activity needs to be
 * restarted due to, for example, a configuration change.  This is a lot
 * easier than using the raw Activity.onRetainNonConfiguratinInstance() API.
 */
public class FragmentRetainInstance extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // First time init, create the UI.
        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction().add(android.R.id.content,
                    new UiFragment()).commit();
        }
    }

    /**
     * This is a fragment showing UI that will be updated from work done
     * in the retained fragment.
     */
    public static class UiFragment extends Fragment {
        RetainedFragment mWorkFragment;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_retain_instance, container, false);

            // Watch for button clicks.
            Button button = (Button)v.findViewById(R.id.restart);
            button.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    mWorkFragment.restart();
                }
            });

            return v;
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

            FragmentManager fm = getFragmentManager();

            // Check to see if we have retained the worker fragment.
            mWorkFragment = (RetainedFragment)fm.findFragmentByTag("work");

            // If not retained (or first time running), we need to create it.
            if (mWorkFragment == null) {
                mWorkFragment = new RetainedFragment();
                // Tell it who it is working with.
                mWorkFragment.setTargetFragment(this, 0);
                fm.beginTransaction().add(mWorkFragment, "work").commit();
            }
        }

    }

    /**
     * This is the Fragment implementation that will be retained across
     * activity instances.  It represents some ongoing work, here a thread
     * we have that sits around incrementing a progress indicator.
     */
    public static class RetainedFragment extends Fragment {
        ProgressBar mProgressBar;
        int mPosition;
        boolean mReady = false;
        boolean mQuiting = false;

        /**
         * This is the thread that will do our work.  It sits in a loop running
         * the progress up until it has reached the top, then stops and waits.
         */
        final Thread mThread = new Thread() {
            @Override
            public void run() {
                // We'll figure the real value out later.
                int max = 10000;

                // This thread runs almost forever.
                while (true) {

                    // Update our shared state with the UI.
                    synchronized (this) {
                        // Our thread is stopped if the UI is not ready
                        // or it has completed its work.
                        while (!mReady || mPosition >= max) {
                            if (mQuiting) {
                                return;
                            }
                            try {
                                wait();
                            } catch (InterruptedException e) {
                            }
                        }

                        // Now update the progress.  Note it is important that
                        // we touch the progress bar with the lock held, so it
                        // doesn't disappear on us.
                        mPosition++;
                        max = mProgressBar.getMax();
                        mProgressBar.setProgress(mPosition);
                    }

                    // Normally we would be doing some work, but put a kludge
                    // here to pretend like we are.
                    synchronized (this) {
                        try {
                            wait(50);
                        } catch (InterruptedException e) {
                        }
                    }
                }
            }
        };

        /**
         * Fragment initialization.  We way we want to be retained and
         * start our thread.
         */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // Tell the framework to try to keep this fragment around
            // during a configuration change.
            setRetainInstance(true);

            // Start up the worker thread.
            mThread.start();
        }

        /**
         * This is called when the Fragment's Activity is ready to go, after
         * its content view has been installed; it is called both after
         * the initial fragment creation and after the fragment is re-attached
         * to a new activity.
         */
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

            // Retrieve the progress bar from the target's view hierarchy.
            mProgressBar = (ProgressBar)getTargetFragment().getView().findViewById(
                    R.id.progress_horizontal);

            // We are ready for our thread to go.
            synchronized (mThread) {
                mReady = true;
                mThread.notify();
            }
        }

        /**
         * This is called when the fragment is going away.  It is NOT called
         * when the fragment is being propagated between activity instances.
         */
        @Override
        public void onDestroy() {
            // Make the thread go away.
            synchronized (mThread) {
                mReady = false;
                mQuiting = true;
                mThread.notify();
            }

            super.onDestroy();
        }

        /**
         * This is called right before the fragment is detached from its
         * current activity instance.
         */
        @Override
        public void onDetach() {
            // This fragment is being detached from its activity.  We need
            // to make sure its thread is not going to touch any activity
            // state after returning from this function.
            synchronized (mThread) {
                mProgressBar = null;
                mReady = false;
                mThread.notify();
            }

            super.onDetach();
        }

        /**
         * API for our UI to restart the progress thread.
         */
        public void restart() {
            synchronized (mThread) {
                mPosition = 0;
                mThread.notify();
            }
        }
    }
}



管理Fragments
在activity中要管理fragment就要用到FragmentManager,可以在activity中通过方法getFragmentManager()获取。
你可以用Fragmentmanager做如下几件事:
通过findFragmentById()(有UI的Fragment)或者findFragmentByTag()(有和无UI的Fragment)这两个方法取得activity中已有的fragment.
通过popBackStack()从back栈中弹出一个fragment
通过addOnBackStackChangedListener()注册一个监听器监听back栈的变化。

你也可以用FragmentManager打开一个FragmentTransaction来执行Fragment事务,例如添加和移除fragment。

执行Fragment事务
添加,移除,替代或其他一些用户操作是fragment的最好的一个能力体现,每一个你提交到activity的动作都叫做一个事务,可以通过FragmentTransaction来操作。
可以如下从fragmentmanager中获得fragmentTransaction实例:

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

每一个事务都是在同一时间要执行的一组改动。你可以用add(),remove(),replace()这几个方法来发起
改动,然后调用commit()方法把你的改动提交给activity。
在你commit()前,你可能需要调用方法addToBackStack()把事务添加到当前activity管理的back栈中,这可以让用户通过按back按钮返回到之前的fragment状态。
例如,这有个例子用fragment做了替换操作并把该事务保存到back栈中
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

在这个例子中,newFragment替换了当前资源ID为R.id.fragment_container的layout中的fragment,而并不需要知道被替换掉的是哪个fragment。通过调用addToBackStack(),替换fragment这一事务操作被保存到了back栈中,这是可以按back按钮来返回的。
注意:如果你在事务中进行了多项操作比如add(),然后remove(),然后replace()再去addToBackStack(),这样的话在你调用commit()前的所有操作
。。。。
。。。
。。

写到一般发现网上有好多类似或一样的,剩下的就不发了。





分享到:
评论

相关推荐

    Android官方API文档完整版

    Android官方API文档是开发者在构建Android应用程序时的重要参考资料,它详尽地涵盖了Android系统的各个方面,包括框架API、库、工具以及开发过程中的最佳实践。这个完整版的文档以CHM(Compiled HTML Help)格式提供...

    jdk1.8中文api Android官方API文档完整版

    Java JDK 1.8中文API和Android官方API文档是开发者必备的参考资料,它们详细阐述了这两个平台的核心功能和使用方法。下面将分别介绍这两个API的主要内容,并探讨它们在实际开发中的应用。 首先,JDK 1.8是Java ...

    Android官方API文档完整版2017

    《Android官方API文档完整版2017》是Android开发者不可或缺的重要参考资料,它详细记录了Android平台的各种API接口、类库、方法以及相关的使用指南。这份文档覆盖了Android开发的各个方面,包括系统服务、UI框架、...

    Android官方API文档-完整版

    Android官方API文档是开发者了解和使用Android平台进行应用开发的重要参考资料。这份完整版的文档包含了从早期版本到较旧版本的大部分API,虽然可能没有涵盖最新SDK中的所有更新,但其内容仍然非常全面,对开发者来...

    Android官方API文档完整版.zip

    Android官方API文档是开发者在构建Android应用程序时的重要参考资料,它详尽地介绍了Android系统的各种组件、接口、类库以及方法。这份"Android_api文档_快速查询"的压缩包包含了一个名为"Android官方API文档完整版....

    Android API文档完整版

    10. **测试与性能优化**:Android API文档也包含测试框架(如JUnit、Espresso)和性能优化工具的介绍,如内存分析、CPU使用率监控、布局性能分析等,帮助开发者创建高效稳定的应用。 总之,"Android API文档完整版...

    AndroidAPI官方文档完整版

    Android API官方文档是Android开发者的重要...以上只是Android API文档中的冰山一角,文档还包含了详细的API参考、示例代码、最佳实践以及开发者指南等内容,是开发者解决问题、学习新技术和提升开发技能的强大资源。

    Android API中文帮助文档合集

    综上,Android API中文帮助文档合集是开发者不可或缺的工具,它全面介绍了Android开发的各个方面,有助于开发者快速学习和解决实际问题。无论你是初学者还是经验丰富的开发者,这个文档都将是你探索Android世界的...

    android API 中文文档

    在探讨这份android API中文文档之前,需要明确Android API文档是Android开发者日常工作中不可或缺的参考资料。这份文档详细地描述了Android平台上各个组件的使用方法和属性设置,涵盖了从基础控件到高级功能的广泛...

    Android 2.2的API文档-chm格式,搜索方便

    Android 2.2 API文档是开发者们理解和使用Android平台的重要参考资料。这个CHM(Compiled HTML Help)格式的文档集合提供了全面、详细的API接口和类库信息,使得在开发过程中查找和学习API变得更为便捷。 CHM文件是...

    android中文API文档以及经典例子

    通过阅读这份中文API文档和实践其中的经典例子,开发者不仅可以掌握Android开发的基本技能,还能了解到如何优化应用性能,提高用户体验。对于初学者和有经验的开发者来说,这都是一个不可多得的学习资源。

    android-API文档

    Android API文档是开发者在进行Android应用开发时的重要参考资料,它详细阐述了Android系统的各个组件、接口、类库以及方法的使用。这篇文档集合了多个Android技术分支,为开发者提供了全面的指南。 首先,我们来看...

    Vue.js 3.0 API 官方手册 中文pdf版(含源码).zip

    这份“Vue.js 3.0 API 官方手册 中文pdf版”是学习Vue 3的重要资源,它详尽地解释了新版本中的各种特性、接口和最佳实践。 1. **Composition API**: Vue 3 引入了Composition API,允许开发者将逻辑组件化,提高...

    安卓(android)帮助文档API中文版全集

    Android API中文版全集是针对开发者的重要资源,它包含了大量的开发指南、参考文档、API接口详解以及示例代码,使得中国开发者能够更方便地理解和使用Android平台进行应用开发。 这个压缩包文件“AndroidBox0.5”很...

    FragmentActivity源码下载

    此文档将对`FragmentActivity`的源代码进行深入分析,以便理解其内部机制及其与系统其他部分的交互方式。 #### 二、源码背景 `FragmentActivity`是Android Support Library的一部分,旨在为Android 3.0(API级别11...

    Android中文API文档

    Android中文API文档是开发者在进行Android应用开发时的重要参考资料,特别是4.0版本,它涵盖了Android SDK中的各种接口、类库以及系统服务的详细说明。这个文档为开发者提供了丰富的信息,帮助他们理解和利用Android...

    使用fragment创建动态UI

    根据给定文件的信息,本文将详细介绍如何使用Android Fragment创建动态用户界面(UI)。Android Fragment是Android开发中的一个重要组件,它允许开发者在一个Activity中动态地组合多个片段来构成复杂的UI布局。 ...

    android api文档

    Android API文档是Android开发者不可或缺的资源,它详细阐述了Android平台的各种接口、类库和工具,帮助开发者构建高质量的应用程序。这份"Android中文开发文档"是针对中文用户特别准备的,旨在让Android开发过程...

Global site tag (gtag.js) - Google Analytics