转载请注明出处:http://blog.csdn.net/h28496/article/details/44412263
什么是Fragment
有一个播放器,在安卓平板上,由于显示面积大,我们可以把播放列表和歌词界面同时显示。但是在手机上呢,由于屏幕较小,我们只能把音乐列表和歌词界面分开。如果没有Fragment,我们只能设计两个界面,平板一个,手机一个。但我们都是程序员,程序员讲究代码的可重用性。我们可以把播放列表界面封装成一个界面A,歌词界面封装成另一个界面B。在平板上用A、B组成一个大的界面,在手机上按需要单独显示A或者B界面。在这里A、B就是一个碎片,Fragment。
Fragment是为了解决界面的复用而出现的。
一台电脑有CPU、GPU、硬盘等。当我需要换一块硬盘时,不用更换整台电脑,只需更换硬盘就行了。
像电脑一样,我们可以动态地添加、删除、替换Fragment,而不用涉及修改整个Activity。
Fragment具有自己的生命周期,甚至可以和Activity一样处理事件,例如Button的点击事件。
Fragment的生命周期
Fragment的生命周期
Fragment的视图是在onCreateView()中创建的,该方法需要返回一个View对象。
我们在Activity中 可以这样找控件: findViewById(int id);
但在Fragment中需要加上view。 getView().findViewById(int id);
和Activity的生命周期作比较
场景演示
注:关于场景演示的内容引用自forever_crying的博客
地址:http://blog.csdn.net/forever_crying/article/details/8238863/
切换到该Fragment
onAttach
onCreate
onCreateView
onActivityCreated
onStart
onResume
屏幕灭掉
onPause
onSaveInstanceState
onStop
屏幕解锁
onStart
onResume
切换到其他Fragment:
onPause
onStop
onDestroyView
切换回本身的Fragment:
onCreateView
onActivityCreated
onStart
onResume
回到桌面
onPause
onSaveInstanceState
onStop
回到应用
onStart
onResume
退出应用
onPauseonStop
onDestroyView
onDestroy
onDetach
简单地使用Fragment
Fragment的布局文件
碎片的布局和Activity一样,这是fragment_contact的布局
<?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" >
<TextView
android:id="@+id/contact_tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="联系人" />
</RelativeLayout>
Fragment类的实现
新建一个类,继承Fragment即可。需要重写onCreateView,设置该碎片的布局。
package zhp.app.fragmenttest.myfragments;
import zhp.app.fragmenttest.R;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment_Contact extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_contact, container, false);
}
}
另外还有其他两个Fragment,代码几乎一样,这里就不再贴了。文末有下载链接。
在Activity中使用Fragment
像使用Button一样使用Fragment。
这是MainActivity的布局文件:
<RelativeLayout 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="${relativePackage}.${activityClass}" >
<FrameLayout
android:id="@+id/main_contain"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/bottombar"
android:layout_below="@+id/main_topbar" />
<LinearLayout
android:id="@+id/bottombar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:layout_alignParentBottom="true"
android:background="#f5f5f5"
android:orientation="horizontal" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<Button
android:id="@+id/bottombar_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="@drawable/msg"
android:onClick="onClick" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<Button
android:id="@+id/bottombar_contact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="@drawable/contact"
android:onClick="onClick" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<Button
android:id="@+id/bottombar_dynamic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="@drawable/dynamic"
android:onClick="onClick" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
MainActivity.java
package zhp.app.fragmenttest;
import zhp.app.fragmenttest.myfragments.Fragment_Contact;
import zhp.app.fragmenttest.myfragments.Fragment_Dynamic;
import zhp.app.fragmenttest.myfragments.Fragment_Msg;
import zhp.app.fragmenttest.myfragments.Fragment_TopBar;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
public class MainActivity extends Activity {
// 三个fragment
private Fragment_Msg fMsg;
private Fragment_Contact fContact;
private Fragment_Dynamic fDynamic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
fMsg = new Fragment_Msg();
fContact = new Fragment_Contact();
fDynamic = new Fragment_Dynamic();
changeTo(fMsg);
}
@Override
protected void onStart() {
super.onStart();
fTopBar.changeToMsg();
}
public void onClick(View v){
switch (v.getId()) {
case R.id.bottombar_msg:
changeTo(fMsg);
break;
case R.id.bottombar_contact:
changeTo(fContact);
break;
case R.id.bottombar_dynamic:
changeTo(fDynamic);
break;
}
}
/**
* 替换Fragment
*/
private void changeTo(Fragment fragment){
FragmentManager fm = getFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.main_contain, fragment);
transaction.commit();
}
}
重点在如何替换Fragment。
首先创建一个 碎片管理器,
FragmentManager fm = getFragmentManager();
然后由碎片管理器获得碎片处理对象
FragmentTransaction transaction = fm.beginTransaction
再把R.id.main_contain对应的布局替换为新的fragment
transaction.replace(R.id.main_contain, fragment);
替换完成后,别忘了提交这个替换操作(有点像数据库最后的 go~)
transaction.commit();
Fragment的操作
添加
transaction.add()
往当前Activity添加一个Fragment
移除
transaction.remove()
从Activity中移除Fragment
替换
transaction.replace()
替换在上一节讲过,两个参数:第一个是原来的fragment,第二个是新的fragment。
transaction.replace(旧的, 新的) = transaction.remove(旧的) + transaction.add(新的)
隐藏
transaction.hide()
隐藏一个Fragment,并不是销毁。例如:该碎片中有一个EditText,EditText中已经输入了内容。隐藏之后,里面的内容还在。用transaction.show()可以把隐藏得Fragment显示出来,EditText中的内容还在。
显示
transaction.show()
把隐藏得Fragment显示出来。
hide -> show : 原内容还在
remove -> add : 原内容丢失,类似复位(包括Fragment的变量)。
另外一个移除
transaction.detach()
解除与当前UI的关联,布局复位,但是里面变量的值还在。
另外一个添加
transaction.attach()
重建这个碎片的视图并显示。