Fragment 使用(1)
参考:
片段:https://developer.android.com/guide/components/fragments.html#Managing
Building a Dynamic UI with Fragments:https://developer.android.com/training/basics/fragments/index.html?hl=zh-CN
Fragment:https://developer.android.com/reference/android/app/Fragment.html
Fragment:https://developer.android.com/reference/android/support/v4/app/Fragment.html
有用的知识点:
- fragment必须始终嵌入到Activity中,其生命周期直接接受宿主Activity生命周期的影响;
- fragment可以通过在Activity的布局文件xml中声明,作为元素插入布局文件中;
- fragment也可以通过代码进行插入,以这种方式,frament可以动态的进行添加,替换和移除;
- fragment不一定必须成为Activity布局的一部分;
- 没有UI的fragment可以作为Activity的不可见工作线程
最简单的fragment工程
新建一个类FirstFragment,继承Fragment类。当fragment拥有布局文件xml时,FirstFragment必须重载 onCreateView()
函数,将布局文件加载进来:
FristFragment.java如下:
package com.example.fragmentuse;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Lenovo on 2017/2/15.
*/
public class FirstFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// return super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.fragment_main, container, false);
}
}
布局文件fragment_main.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">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/app_name" />
</LinearLayout>
将FirstFragment类加载到Activity中,有两种方式,第一种是在xml中固定加载;第二种是在代码中动态加载。
第一种:
MainActivity.java如下:
package com.example.fragmentuse;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
activity_main.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.fragmentuse.MainActivity">
<fragment
android:id="@+id/fragment"
android:name="com.example.fragmentuse.FirstFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
注1:最好使用支持库的Fragment:android.support.v4.app.Fragment
。
注2:由于Android在 Android 3.0
(API级别11)中开始引入fragment,所以之前版本并没有fragment,如果你想要支持API级别小于11的系统,其Activity需要继承自 android.support.v4.app.FragmentActivity
;而如果 minSdkVersion
大于等于 11,那么常规的Activity也可以。
注3:android.support.v7.app.AppCompatActivity
是 android.support.v4.app.FragmentActivity
的一个子类
第二种:
MainActivity.java代码:
package com.example.fragmentuse;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.fragment_container) != null) {
if (savedInstanceState != null) {
return ;
}
FirstFragment firstFragment = new FirstFragment();
firstFragment.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
}
}
activity_main.xml代码:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
注1:动态添加或移除片段等事务,必须使用 FragmentManager
创建 FragmentTransaction
,后者提供了添加,移除,替换片段以及执行其他片段事务所需的API。
注2:动态添加时,需要在Activity的 onCreate()
方法中添加初始fragment。
注3:处理fragment时,activity布局必须包含一个用来充当fragment容器的view。
注4:使用 add()
函数添加一个fragment,可以使用同一个 FragmentTransaction
处理多个fragment事务,完成修改后,使用 commit()
函数提交
fragment生命周期
核心生命周期函数如下:
onAttach(Activity):当fragment和Activity绑定时调用(called once the fragment is associated with its activity)
onCreate(Bundle):进行fragment的初始创建时调用(called to do initial creation of the fragment)
onCreateView(LayoutInflater, ViewGroup, Bundle):创建并返回与该片段关联的视图层次结构(creates and returns the view hierarchy associated with the fragment)
onActivityCreated(Bundle):告诉fragment,父activity已经完成onCreate()方法(tells the fragment that its activity has completed its own Activity.onCreate())
onViewStateRestored(Bundle):告诉fragment,它的视图层次结构的状态已恢复(tells the fragment that all of the saved state of its view hierarchy has been restored)
onStart():使fragment可见(makes the fragment visible to the user (based on its containing activity being started))
onResume():使fragment和用户交互(makes the fragment begin interacting with the user (based on its containing activity being resumed))
onPause():fragment不再与用户交互,可能原因1:父Activity已经paused;可能原因2:在父Activity中动态修改了fragment(fragment is no longer interacting with the user either because its activity is being paused or a fragment operation is modifying it in the activity)
onStop():fragment不再可见,可能原因1:父Activity已经stoped;可能原因2:在父Activity中动态修改了fragment(fragment is no longer visible to the user either because its activity is being stopped or a fragment operation is modifying it in the activity)
onDestoryView():允许fragment清理与视图相关的资源(allows the fragment to clean up resources associated with its View)
onDestory():进行fragment状态的最终清理(called to do final cleanup of the fragment’s state)
onDetach():当fragment不再和父activity有关联之前调用(called immediately prior to the fragment no longer being associated with its activity)
Activity生命周期对fragment生命周期的影响如下图所示:
![](http://i.imgur.com/tAPcQ7j.png)
下面写一个工程,判断fragment生命周期函数和activity生命周期函数的先后执行顺序:
MainFragment.xml代码:
package com.example.fragment3;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Lenovo on 2017/2/15.
*/
public class MainFragment extends Fragment {
private static final String TAG = MainFragment.class.getSimpleName();
@Override
public void onAttach(Context context) {
super.onAttach(context);
Log.e(TAG, "onAttach: ");
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG, "onCreate: ");
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.e(TAG, "onCreateView: ");
return inflater.inflate(R.layout.fragment_main, container, false);
// return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.e(TAG, "onActivityCreated: ");
}
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
Log.e(TAG, "onViewStateRestored: ");
}
@Override
public void onStart() {
super.onStart();
Log.e(TAG, "onStart: ");
}
@Override
public void onResume() {
super.onResume();
Log.e(TAG, "onResume: ");
}
@Override
public void onPause() {
super.onPause();
Log.e(TAG, "onPause: ");
}
@Override
public void onStop() {
super.onStop();
Log.e(TAG, "onStop: ");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.e(TAG, "onDestroyView: ");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy: ");
}
@Override
public void onDetach() {
super.onDetach();
Log.e(TAG, "onDetach: ");
}
}
fragment_main.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">
<TextView
android:id="@+id/fm_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/app_name" />
</LinearLayout>
MainActivity.java代码:
package com.example.fragment3;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(TAG, "onCreate: ");
}
@Override
protected void onStart() {
super.onStart();
Log.e(TAG, "onStart: ");
}
@Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume: ");
}
@Override
protected void onRestart() {
super.onRestart();
Log.e(TAG, "onRestart: ");
}
@Override
protected void onPause() {
super.onPause();
Log.e(TAG, "onPause: ");
}
@Override
protected void onStop() {
super.onStop();
Log.e(TAG, "onStop: ");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy: ");
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.fragment3.MainActivity">
<fragment
android:name="com.example.fragment3.MainFragment"
android:id="@+id/am_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
运行结果如下:
情况1:启动,退出
![](http://i.imgur.com/Y3QGC6T.png)
情况2:启动,暂停,再恢复,最后退出
启动:
![](http://i.imgur.com/lnEo3of.png)
暂停:
![](http://i.imgur.com/GGmHnMe.png)
恢复:
![](http://i.imgur.com/y3vmTUX.png)
退出:
![](http://i.imgur.com/MAAiAHj.png)