Android片段生命周期
今天,我们将学习Android Fragment Lifecycle,并在android应用程序中实现由两个片段组成的单个活动类。
Android片段
Android中的Fragment类用于构建动态用户界面。
片段应在活动内使用。
片段的最大优点是,它简化了为多种屏幕尺寸创建UI的任务。
一个活动可以包含任意数量的片段。
Android片段本身并不是大多数其他UI组件都是View的子类。
相反,片段内部有一个视图。
该视图最终显示在片段所在的活动中。
由于android片段不是视图,因此将其添加到活动中看起来与添加视图(例如TextView)有所不同。
片段被添加到活动内部的ViewGroup中。
片段的视图显示在此ViewGroup中。
下图显示了将片段添加到活动时发生的情况:
首先,活动获得对该片段的引用。
然后,它获取对ViewGroup的引用,该片段的视图将其中呈现。
然后,活动添加片段。
然后,该片段创建其视图并将其返回到活动。
然后将视图插入到ViewGroup父级中,并且该片段处于活动状态。
片段生命周期
下图说明了Android片段的生命周期。
以下是片段生命周期的方法。
onAttach():即使在onCreate()之前,也会首先调用此方法,让我们知道您的片段已附加到活动中。
您通过了将托管您的片段的活动onCreateView():当片段第一次绘制其UI时,系统调用此回调。
要绘制片段的UI,必须从此方法返回View组件,该组件是片段布局的根。
如果片段不提供UI,我们可以返回nullonViewCreated():将在onCreateView()之后调用。
这在继承onCreateView()实现时特别有用,但是我们需要配置结果视图,例如使用ListFragment以及何时设置适配器onActivityCreated():将在onCreate()和onCreateView()之后调用,以指示活动的onCreate()已完成。
如果片段中需要初始化的内容取决于活动的onCreate()完成工作,则可以使用onActivityCreated()进行初始化工作onStart():一旦可见片段,就会调用onStart()方法onPause():系统调用此方法作为用户离开该片段的第一个指示。
通常,您应该在此处提交应保留在当前用户会话之后的所有更改。onStop():通过调用onStop()将片段停止onDestroyView():在onDestroy()之前调用。
这与设置UI的onCreateView()相对。
如果需要针对UI进行清理,则可以将该逻辑放在onDestroyView()中。onDestroy():onDestroy()被调用以对片段的状态进行最终清理,但不能保证由Android平台调用。
onDetach():在onDestroy()之后调用,以通知该片段已从其托管活动中取消关联
Android片段类
片段已添加到Honeycomb(API 11)中的Android API中。
android.app.Fragment:所有片段定义的基类android.app.FragmentManager:用于与活动内的片段对象进行交互的类- android.app.FragmentTransaction:用于执行片段操作的原子集的类
使用Google提供的兼容性软件包库时,以下类用于实现。
- android.support.v4.app.FragmentActivity:使用基于兼容性的片段(和加载程序)功能进行的所有活动的基类
- android.support.v4.app.Fragment
- android.support.v4.app.FragmentManager
- android.support.v4.app.FragmentTransaction
Android片段onCreateView()
这是使用onCreateView()实现的示例片段:
public class SampleFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parentViewGroup,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_sample, parentViewGroup, false);
return rootView;
}
}
onCreateView()方法获取LayoutInflater,ViewGroup和Bundle作为参数。
LayoutInflater是一个可以基于布局XML文件创建View实例的组件。
如您所见,该示例实际上通过调用layout.inflate()来实现。
inflate()方法采用三个参数:布局XML文件的ID(在R.layout内部),要插入片段的View的父ViewGroup,以及第三个布尔值,用于告知片段的View是否从布局XML文件应插入父级ViewGroup中。
在这种情况下,我们将传递false,因为View将通过我们调用的某些Android代码附加到父ViewGroup的其他位置。
当您将false作为最后一个参数传递给inflate()时,父ViewGroup仍用于膨胀View的布局计算,因此您不能将null作为父ViewGroup传递。
onCreateView()的ViewGroup参数是要插入片段的View的父ViewGroup。
这是活动内部的ViewGroup,将"托管"片段。
onCreateView()的Bundle参数是一个Bundle,片段可以其中保存数据,就像在Activity中一样。
Android片段示例
Android片段示例项目包含一个包含两个片段的单独活动:分别为TextFragment和MenuFragment。
Android片段示例代码
MainActivity包含两个片段TextFragment和MenuFragment。
因此,让我们开始在xml布局中定义片段
activity_main.xml
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="1.0">
<fragment
android:layout_height="match_parent"
android:layout_width="match_parent"
class="theitroad.local.fragments.fragments.MenuFragment"
android:id="@+id/fragment"
android:layout_weight="0.5"
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
class="theitroad.local.fragments.fragments.TextFragment"
android:id="@+id/fragment2"
android:layout_weight="0.5"
</LinearLayout>
我们可以看到,作为该活动一部分的片段的类文件被定义为class =" theitroad.local.fragments.fragments.TextFragment"
片段类及其布局的定义如下面的代码片段所示。
package theitroad.local.fragments.fragments;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import theitroad.local.fragments.R;
public class TextFragment extends Fragment {
TextView text,vers;
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.text_fragment, container, false);
text= (TextView) view.findViewById(R.id.AndroidOs);
vers= (TextView)view.findViewById(R.id.Version);
return view;
}
public void change(String txt, String txt1){
text.setText(txt);
vers.setText(txt1);
}
}
text_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:gravity="center"
android:background="#5ba4e5"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40px"
android:textColor="#ffffff"
android:layout_gravity="center"
android:id="@+id/AndroidOs"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#ffffff"
android:textSize="30px"
android:id="@+id/Version"
</LinearLayout>
TextFragment由保存Android版本名称和编号的文本视图组成。
package theitroad.local.fragments.fragments;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import theitroad.local.fragments.R;
public class MenuFragment extends ListFragment {
String[] AndroidOS = new String[] { "Cupcake","Donut","Eclair","Froyo","Gingerbread","Honeycomb","Ice Cream SandWich","Jelly Bean","KitKat" };
String[] Version = new String[]{"1.5","1.6","2.0-2.1","2.2","2.3","3.0-3.2","4.0","4.1-4.3","4.4"};
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
View view =inflater.inflate(R.layout.list_fragment, container, false);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, AndroidOS);
setListAdapter(adapter);
return view;
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
TextFragment txt = (TextFragment)getFragmentManager().findFragmentById(R.id.fragment2);
txt.change(AndroidOS[position],"Version : "+Version[position]);
getListView().setSelector(android.R.color.holo_blue_dark);
}
}
list_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@android:id/list"
</LinearLayout>
MenuFragment显示一个ListView。
正如我们在这里看到的,ListView的布局是默认的simple_list_item_1,与我们在上一篇文章中为ListView创建的自定义布局相反。
MainActivity从onCreate方法调用setContentView就是这样。
这些片段是从xml文件中调用的。
或者,我们可以使用" FragmentManager"从活动类中添加片段,如下面的代码片段所示:
getFragmentManager()
.beginTransaction()
.add(R.id.fragmentParentViewGroup, new MyFragment())
.commit();
此处idfragmentParentViewGroup属于以下所示的FrameLayout:
<FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:id="@+id/fragmentParentViewGroup"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity"
tools:ignore="MergeRootFrame"

