Android片段

时间:2020-01-09 10:34:00  来源:igfitidea点击:

Android片段是一个GUI组件,可以"存在"于"活动"内部。 Android片段本身并不是大多数其他GUI组件都是的View的子类。相反,片段内部有一个视图。最终将在片段所在的活动内部显示此视图。

由于Android片段不是视图,因此将其添加到活动中看起来与添加视图有些不同(例如TextView)。片段被添加到活动内的" ViewGroup"中。片段的视图显示在此" ViewGroup"中。下图显示了向活动添加片段时发生的情况:

首先,活动获得对该片段的引用。然后,它获取对ViewGroup的引用,该片段的视图将其中呈现。然后,活动将添加片段。然后,该片段创建其视图并将其返回到活动。然后将视图插入到ViewGroup父级中,并且该片段处于活动状态。

创建片段

要创建片段,我们必须做两件事:

  • `创建一个片段类。
  • 创建一个片段布局XML文件。

创建一个片段类

要创建Fragment类,请创建一个扩展了android.app.Fragment的普通Java类。这是一个例子:

import android.app.Fragment;

public class MyFragment extends Fragment {

}

onCreateView()

这个Fragment子类还没有做任何事情。 MyFragment类需要重写从Fragment继承的onCreateView()方法,以创建片段的View,该View将在添加片段的活动中显示。这是片段示例onCreateView()的实现:

public class MyFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parentViewGroup,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_my, parentViewGroup, false);
        return rootView;
    }
}

onCreateView()方法获取一个layoutInflater,一个ViewGroup和一个Bundle作为参数。

" LayoutInflater"是一个可以基于布局XML文件创建" View"实例的组件。如我们所见,该示例实际上是通过调用layout.inflate()来实现的。

inflate()方法具有三个参数:布局XML文件的ID(在R.layout内部),将片段的View插入其中的父ViewGroup和第三个布尔值。判断是否应将从布局XML文件扩展来的片段的"视图"插入父级"视图组"中。在这种情况下,我们传递了false,因为View将会通过我们调用的某些Android代码(换句话说,在背后)添加到父ViewView的其他位置。当我们将false作为最后一个参数传递给inflate()时,父ViewGroup仍用于膨胀的View的布局计算,因此我们不能将null作为父ViewGroup传递。

onCreateView()的ViewGroup参数是父ViewGroup,片段的View将插入其中。这是活动内部的" ViewGroup",将"托管"该片段。

onCreateView()的Bundle参数是一个Bundle,片段可以将信息保存到其中,就像Activity一样。

向活动添加片段

为了在活动中显示片段的"视图",必须将片段添加到活动中。我们可以在活动中执行此操作。这是一个从活动的oncreate()内部添加片段的示例:

public class MyActivity extends Activity {

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

        if (savedInstanceState == null) {
            getFragmentManager()
                    .beginTransaction()
                    .add(R.id.fragmentParentViewGroup, new MyFragment())
                    .commit();
        }
    }

}

该片段被添加到if语句中。与其他"视图"组件不同,该活动会记住向该活动中添加了哪些片段。因此,我们仅应在活动的生命周期内向该活动添加一个片段,否则该片段将出现多次。即使用户在纵向和横向之间更改设备的方向,即使活动在此过程中被破坏,也是如此。 Android操作系统会记住在创建此类新活动时向该活动添加了一个片段,并将该片段重新添加到该活动。

如果savedInstanceState为null,则这是第一次为该活动创建任何状态,因此尚未向其添加任何片段。记住,如果一个应用程序被Android完全销毁了,它的savedInstanceState``Bundle变量也会被销毁,那么在活动开始时,我们需要重新添加该片段。

片段必须在" FragmentTransaction"内部添加(或者替换或者删除)。我们可以通过" FragmentManager"获得" FragmentTransaction"。我们可以通过getFragmentManager()方法获得FragmentManager。从" FragmentManager"中,我们可以通过调用" beginTransaction()"方法获得" FragmentTransaction"。现在,在由beginTransaction()返回的" FragmentTransaction"上,我们可以添加,替换或者删除活动中的片段。

是FragmentTransaction上的add()方法将片段添加到活动中。 add()方法有两个参数。第一个参数是要插入片段的"视图"的父"视图组"的ID。第二个参数是要添加的片段的实例。

完成添加,替换或者删除片段后,我们必须提交FragmentTransaction。为此,我们可以通过调用FragmentTransaction中的commit()方法来实现。仅当FragmentTransaction提交后,我们所做的所有更改才会生效。

这是活动的布局XML文件。请注意,根元素的ID与R.layout常量集合中引用的ID相同。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:id="@+id/fragmentParentViewGroup"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             tools:context=".MyActivity"
             tools:ignore="MergeRootFrame" />

这个布局XML文件只有一个FrameLayout元素。这个FrameLayout元素被用作片段的父ViewGroup。因此,在实践中,片段将占据整个屏幕。我们可以使用其他ViewGroup作为该片段的父对象。这是一个活动布局XML文件示例,显示了外观:

<LinearLayout 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"
              android:orientation="vertical"
              tools:context=".MyActivity"

        >

    <TextView
            android:text="Activity Title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />

    <LinearLayout
            android:id="@+id/fragmentParentViewGroup"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

    </LinearLayout>

</LinearLayout>

注意内部的LineLayout元素如何具有idfragmentParentViewGroup。该片段将使用此LinearLayout作为父ViewGroup。

碎片生命周期

Android片段的生命周期类似于活动生命周期。片段生命周期如下所示:

首先,将片段添加到活动中。这开始了片段的生命周期。

其次,调用方法onAttach(),onCreate(),onCreateView(),onActivityCreated(),onStart()和onResume()。完全创建托管活动后,将调用onActivityCreated()。

如果将片段从其托管活动中删除,或者将托管片段的活动移至应用程序的后台(另一个活动移至前台),则onPause(),onStop()和onDestroyView ()`方法被调用。如果片段返回可见性,则片段可以从onDestroyView()过渡到onCreateView()并再次变得可见。

替换片段

我们可以用另一个片段替换添加到活动中的片段。我们可以通过" FragmentTransaction"对象上的" replace()"方法来实现。这是一个" FragmentTransaction"replace()示例:

getFragmentManager().beginTransaction()
    .replace(R.id.fragmentParentViewGroup, new MySecondFragment())
    .commit();

我们可以在活动仍处于活动状态时替换片段。活动销毁后,我们将无法再替换其中的碎片。

我们可以根据需要多次替换片段。我们可以替换片段,以更改部分用户界面,或者更改整个用户界面(如果我们需要/喜欢)。

删除碎片

我们可以使用" FragmentTransaction"从活动中删除片段。我们可以通过remove()方法来实现。这是一个" FragmentTransaction"remove()示例:

getFragmentManager().beginTransaction()
        .remove(mySecondFragment)
        .commit();

remove()方法有一个参数:对要删除的片段的引用。该片段将从添加该片段的任何父" ViewGroup"中删除。

将片段事务添加到后台堆栈

我们可以将片段事务添加到后台堆栈。后退堆栈可跟踪我们应用中的操作,当用户单击设备上的Android标准"后退"按钮时,这些操作可以后退。如果将片段事务添加到后台堆栈,则可以通过单击设备上的"后退"按钮来回溯(撤消)事务。

这是显示如何将片段事务添加到后台堆栈的示例:

MySecondFragment mySecondFragment = new MySecondFragment();

getFragmentManager().beginTransaction()
        .replace(R.id.fragmentParentViewGroup, mySecondFragment)
        .addToBackStack(null)
        .commit();

此示例用MySecondFragment实例替换ID为R.id.fragmentParentViewGroup的任何已添加到父视图组的片段。该示例还将替换事务添加到后台堆栈。 addToBackStack()方法采用可选的String参数,该参数可以标识后退堆栈上的此状态。在大多数情况下,我们不需要此参数,因此传递`null'就足够了。

提交此替换事务后,可以通过用户单击Android设备的"后退"按钮来撤消它,以相同的方式,"后退"按钮可以将用户带回到先前可见的活动。