您的位置:首页 > 移动开发 > Android开发

android Fragment动态加载的使用详解

2016-12-19 22:09 387 查看
在上一节中讲了静态加载,使用静态加载的场景非常局限,因此这里详细讲解动态加载Fragment,这也是开发中常用的使用场景。Fragment是activity的界面中的一部分或一种行为。你可以把多个Fragment们组合到一个activity中来创建一个多面界面并且你可以在多个activity中重用一个Fragment。你可以把Fragment认为模块化的一段activity,它具有自己的生命周期,接收它自己的事件,并可以在activity运行时被添加或删除。

一 生命周期

这里用一张图详细说明Fragment的生命周期。



通常这几个方法比较常用::

onCreate() 
The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.
在创建fragment时系统会调用此方法。在实现代码中,你可以初始化想要在fragment中保持的那些必要组件(这里的组件是指除了view之外的东西,比如需要进行界面展示的关键数据),当fragment处于暂停或者停止状态之后可重新启用它们。

onCreateView() 
The system calls this when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View from this method that is the root of your fragment's
layout. You can return null if the fragment does not provide a UI. 
在第一次为fragment绘制用户界面时系统会调用此方法。为fragment绘制用户界面,这个函数必须要返回所绘出的fragment的根View。如果fragment没有用户界面可以返回空。

onPause() 
The system calls this method as the first indication that the user is leaving the fragment (though it does not always mean the fragment is being destroyed). This is usually where you should commit any changes
that should be persisted beyond the current user session (because the user might not come back). 
系统回调用该函数作为用户离开fragment的第一个预兆(尽管这并不总意味着fragment被销毁)。在当前用户会话结束之前,通常要在这里提交任何应该持久化的变化(因为用户可能不再返回)。

二 布局文件

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context="com.example.dfragmentdemo.MainActivity" >

<FrameLayout android:layout_width="match_parent"
android:layout_weight="1"
android:id="@+id/content"
android:layout_height="match_parent"></FrameLayout>

<View android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000"/>
<LinearLayout android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_alignParentBottom="true">
<ImageView android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="1"
android:id="@+id/tuijian_iv"
android:src="@drawable/tuijian1"/>
<ImageView android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="1"
android:id="@+id/daohang_iv"
android:src="@drawable/daohang1"/>
<ImageView android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="1"
android:id="@+id/faxian_iv"
android:src="@drawable/faxian1"/>
<ImageView android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="1"
android:id="@+id/wode_iv"
android:src="@drawable/wode1"/>
<ImageView android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="1"
android:id="@+id/lixian_iv"
android:src="@drawable/lixian1"/>
</LinearLayout>

</LinearLayout>
tuijian_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00" >

<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="推荐"
android:textSize="30sp"
android:layout_centerInParent="true"/>
</RelativeLayout>
还有其他四个Fragment布局文件和tuijian_main.xml类似,这里就不粘贴了。
三 创建Fragment

创建Tuijian.java,继承import android.support.v4.app.Fragment,并实现onCreateView(),其他的方法先作为日志输出查看生命周期使用。

package com.example.dfragmentdemo;

import android.content.Con
d4a4
text;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Tuijian extends Fragment {
@Override
@Nullable
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.i(ACTIVITY_TAG, "onCreateView");
return inflater.inflate(R.layout.tuijian_main, container, false);
}
private static final String ACTIVITY_TAG="TuijianFragment";
@Override
public void onAttach(Context context) {
// TODO Auto-generated method stub
super.onAttach(context);
Log.i(ACTIVITY_TAG, "onAttach");
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i(ACTIVITY_TAG, "onCreate");
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
Log.i(ACTIVITY_TAG, "onActivityCreated");
}

@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i(ACTIVITY_TAG, "onStart");
}

@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i(ACTIVITY_TAG, "onResume");
}

@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.i(ACTIVITY_TAG, "onPause");
}

@Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.i(ACTIVITY_TAG, "onStop");
}

@Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
Log.i(ACTIVITY_TAG, "onDestroyView");
}

@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i(ACTIVITY_TAG, "onDestroy");
}
@Override
public void onDetach() {
// TODO Auto-generated method stub
super.onDetach();
Log.i(ACTIVITY_TAG, "onDetach");
}
}
其他的四个Fragment也是差不多,这里也不粘贴了。
四 在MainActiviy中实现动态加载Fragment

通过点击导航栏按钮中的button即可加载不同的Fragment

package com.example.dfragmentdemo;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

public class MainActivity extends FragmentActivity {
private ImageView tuijian_iv;
private ImageView daohang_iv;
private ImageView faxian_iv;
private ImageView wode_iv;
private ImageView lixian_iv;
FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;
private Tuijian tuijian;
private Daohang daohang;
private Faxian faxian;
private Wode wode;
private Lixian lixian;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tuijian_iv = (ImageView) findViewById(R.id.tuijian_iv);
daohang_iv = (ImageView) findViewById(R.id.daohang_iv);
faxian_iv = (ImageView) findViewById(R.id.faxian_iv);
wode_iv = (ImageView) findViewById(R.id.wode_iv);
lixian_iv = (ImageView) findViewById(R.id.lixian_iv);

tuijian_iv.setImageResource(R.drawable.tuijian2);

tuijian_iv.setOnClickListener(new MyOnClickListener());
daohang_iv.setOnClickListener(new MyOnClickListener());
faxian_iv.setOnClickListener(new MyOnClickListener());
wode_iv.setOnClickListener(new MyOnClickListener());
lixian_iv.setOnClickListener(new MyOnClickListener());

fragmentManager = getSupportFragmentManager();
SelectFragment(0);

}
private void RemoveFragment(FragmentTransaction fragmentTransaction){
if (tuijian!=null) {
fragmentTransaction.remove(tuijian);
}
if (daohang!=null) {
fragmentTransaction.remove(daohang);
}
if (faxian!=null) {
fragmentTransaction.remove(faxian);
}
if (wode!=null) {
fragmentTransaction.remove(wode);
}
if (lixian!=null) {
fragmentTransaction.remove(lixian);
}
}

private void HideFragment(FragmentTransaction fragmentTransaction){
if (tuijian!=null) {
fragmentTransaction.hide(tuijian);
}
if (daohang!=null) {
fragmentTransaction.hide(daohang);
}
if (faxian!=null) {
fragmentTransaction.hide(faxian);
}
if (wode!=null) {
fragmentTransaction.hide(wode);
}
if (lixian!=null) {
fragmentTransaction.hide(lixian);
}
}
private void SelectFragment(int index) {
fragmentTransaction = fragmentManager
.beginTransaction();
//RemoveFragment(fragmentTransaction);
HideFragment(fragmentTransaction);
switch (index) {
case 0:
if (tuijian==null) {
tuijian = new Tuijian();
fragmentTransaction.add(R.id.content, tuijian);
}
fragmentTransaction.show(tuijian);
break;
case 1:
if (daohang==null) {
daohang = new Daohang();
fragmentTransaction.add(R.id.content, daohang);
}
fragmentTransaction.show(daohang);
break;
case 2:
if (faxian==null) {
faxian = new Faxian();
fragmentTransaction.add(R.id.content, faxian);
}
fragmentTransaction.show(faxian);
break;
case 3:
if (wode==null) {
wode = new Wode();
fragmentTransaction.add(R.id.content, wode);
}
fragmentTransaction.show(wode);

break;
case 4:
if (lixian==null) {
lixian = new Lixian();
fragmentTransaction.add(R.id.content, lixian);
}
fragmentTransaction.show(lixian);
break;
}
fragmentTransaction.commit();
}

private void ClearImage() {
tuijian_iv.setImageResource(R.drawable.tuijian1);
daohang_iv.setImageResource(R.drawable.daohang1);
faxian_iv.setImageResource(R.drawable.faxian1);
wode_iv.setImageResource(R.drawable.wode1);
lixian_iv.setImageResource(R.drawable.lixian1);
}

class MyOnClickListener implements OnClickListener {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ClearImage();
switch (v.getId()) {
case R.id.tuijian_iv:
tuijian_iv.setImageResource(R.drawable.tuijian2);
SelectFragment(0);
break;
case R.id.daohang_iv:
daohang_iv.setImageResource(R.drawable.daohang2);
SelectFragment(1);
break;
case R.id.faxian_iv:
faxian_iv.setImageResource(R.drawable.faxian2);
SelectFragment(2);
break;
case R.id.wode_iv:
wode_iv.setImageResource(R.drawable.wode2);
SelectFragment(3);
break;
case R.id.lixian_iv:
lixian_iv.setImageResource(R.drawable.lixian2);
SelectFragment(4);
break;
}
}

}
}
说明:

android.app.Fragment 主要用于定义Fragment
android.app.FragmentManager 主要用于在Activity中操作Fragment
android.app.FragmentTransaction 保证一些列Fragment操作的原子性
获取FragmentManage的方式有:android.app.Fragment:getFragmentManager() ;android.support.v4.app.Fragment:getSupportFragmentManager

FragmentTransaction
transaction = fm.benginTransatcion()用来开启一个事务

transaction.add() 

往Activity中添加一个Fragment

transaction.remove()

从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁;数据会被销毁。

transaction.replace()

使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体。

transaction.hide();[b]transaction.show()[/b]

隐藏当前的Fragment,仅仅是设为不可见,并不会销毁,显示之前隐藏的Fragment,数据不会销毁。

五  效果:



日志结果:



从日志输出中可以看到和上图的生命周期顺序是一至的,我上面使用的hide和show方法的,所以程序启动后不管怎么切换fragment都不会销毁fragment。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息