1.Fragment 的概述
(1)Fragment是什么
我们都知道,Fragment的翻译可以译为:碎片、片段。在Android开发中引入这一概念的目的是为
了解决不同安卓设备屏幕分辩率不同的问题,引入Fragment碎片技术,可以实现动态和灵活的UI设
计,软件工程师们不需要再对同一款软件进行多次的适应性开发,以便于适应不同屏幕分辨率的安卓设备。
我们可以将Fragment看作是Acitivity的一部分,甚至可以说,整个Activity就是由不同的Fragment组成。更
具有吸引力的是,Fragment有着自己的生命周期和各种处理事件的函数,也就是说,我们不必再将所有的事
件处理都写在Activity中,只需要有一个Fragment专门去处理即可。
(2)Fragment的生命周期
Fragment必须是依存于Activity的,Fragment的生命周期很大程度上受制于Activity。这里放上一张官
网提供的Activity与Fragment生命周期关系说明图。
从图中我们可以看到,在Activity创建时,Fragment也同时被创建,但是Fragment的创建是分为好几步的
onAttach(); //当Activity与Fragment关联时调用
onCreate(); //创建Fragment时调用
onCreateView(); //创建该Fragment的视图
onActivityCreate(); //当Activity的onCreate()方法返回时调用
onDestoryView(); //与onCreateView相对应,当改Fragment被移除时调用
onDestory(); //销毁Fragment时调用
onDetach(); //与onAttach()相对应,当Fragment与Activity的关联被取消时调用
2.静态Fragment 和 动态Fragment
静态Fragment是Fragment最简单的使用方法。我们将主布局文件中加入fragment布局就可,这里我们是将
fragment直接当作一个控件来使用的。
动态Fragment,我们不需要再将fragment的布局文件事先放入主布局中,而是,当我们需要用到的时候,
通过代码,动态的进行加入。
这里有以下几个注意事项:
1.注意每一个fragment的布局都要有一个与之对应的继承于Fragment的类(我们在这里对fragment与activity进行绑定和关联)。
2.关于继承.app.Fragment和.support.v4.app.Fragment的问题:
如果要使用前者,那么MainActivity继承Activity即可,然后动态添加时,是getFragmetManager();
如果使用后者,那么MainActivity要继承FragActivty,然后动态添加时,是getSupportFragmentManager();
3.Fragment 之间的简单通信
在了解了Fragment的基本知识之后,我们最关心的还是Fragment之间是如何进行通信的。如何从一个
fragment向宿主activity发送请求,又如何从activity向fragment发送请求是我们这一节讲述的重点。
首先,我们创建一个Android项目,命名为Fragment。
在Activity.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" >
<EditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="我是activity啊" />
<Button
android:id="@+id/btn1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#76EE00"
android:text="发送信息到左" />
<Button
android:id="@+id/btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#7171C6"
android:text="发送信息到右" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/left_Fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FF3E96"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="@+id/right_Fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#98F5FF"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
</LinearLayout>
左fragment,left.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"
android:orientation="vertical" >
<EditText
android:id="@+id/left_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="我是左啊" />
<Button
android:id="@+id/left_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送信息到activity" />
<Button
android:id="@+id/left_btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送信息到右" />
</LinearLayout>
右fragment,right.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"
android:orientation="vertical" >
<EditText
android:id="@+id/right_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="我是右啊" />
<Button
android:id="@+id/right_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送信息到activity" />
<Button
android:id="@+id/right_btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送信息到左" />
</LinearLayout>
效果图如下所示:
以上我们只是完成了UI布局的编写,以及Fragment碎片的位置,例子中我一共定义了两个碎片,接下来要做的就是让碎片与宿主Activity相关联(这里任意Activity均可)。我们之前提到过,每一个fragment的布局都要有一个与之对应的继承于Fragment的类,以此来进行Fragment的布局绑定和关联必要的Activity,所以,我们必须先定义Fragment的继承类,具体代码如下所示。
左fragment的继承类:
/**LeftFragment.java**/
package com.skylake.fragment;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class LeftFragment extends Fragment {
EditText Left_et;
Button Left_btn;
Button Left_btn2;
TransData td;
TransDataToRight tdtr;
//Fragment与Activity关联后调用
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
td = (TransData) activity;
tdtr = (TransDataToRight) activity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
// inflate()的作用就是将一个用xml定义的布局文件查找出来,
// 注意与findViewById()的区别,inflate是加载一个布局文件,
// 而findViewById则是从布局文件中查找一个控件。
// 关于LayoutInflater类
// inflate(int resource, ViewGroup root, boolean attachToRoot)方法三个参数的含义
// resource:加载的XMl布局资源ID
// root:生成的分层视图的父对象(如果attachToRoot为true),或者是一个简单的提供了一系列布局参数生成的Veiw对象(如果attachToRoot为false)
// attachToRoot:是否要填充的分层视图要添加到父对象中,如果为false。ROOT内容仅仅是初始化,如果要使用,仍需要手动添加。
return inflater.inflate(R.layout.left, null);
}
/**
* public void onViewCreated(View view, Bundle savedInstanceState)
* onCreateView(LayoutInflater, ViewGroup, Bundle)
* 方法返回之后、之前被保存的View对象的状态被恢复之前,系统会立即调用该方法。
* 这样就给子类在了解自己所在的View层次树被完全被创建的情况,提供初始化自己的机会。
* 在这个时点,Fragment对象的View层次树还没有跟它的父对象绑定。
*
* 参数 view 通过onCreateView(LayoutInflater, ViewGroup, Bundle)方法返回的View对象。
* savedInstanceState 如果该参数是非空的(non-null),那么该Fragment对象要使用这个参数中的状态来进行重建。
*/
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(view, savedInstanceState);
Left_et = (EditText) view.findViewById(R.id.left_et);
Left_btn = (Button) view.findViewById(R.id.left_btn);
Left_btn2 = (Button) view.findViewById(R.id.left_btn2);
Left_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
td.setData(Left_et.getText().toString());
}
});
Left_btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
tdtr.setDataToRight(Left_et.getText().toString());
}
});
}
public void setData(String data) {
Left_et.setText(data);
}
public interface TransData{
public void setData(String str);
}
public interface TransDataToRight{
public void setDataToRight(String str);
}
}
右fragment的继承类:
/**RightFragment.java**/
package com.skylake.fragment;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class RightFragment extends Fragment {
EditText Right_et;
Button right_btn;
Button right_btn2;
TransDataX tdx;
TransDataToLeft tdtl;
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
tdx = (TransDataX) activity;
tdtl = (TransDataToLeft) activity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.right, null);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(view, savedInstanceState);
Right_et = (EditText) view.findViewById(R.id.right_et);
right_btn = (Button) view.findViewById(R.id.right_btn);
right_btn2 = (Button) view.findViewById(R.id.right_btn2);
right_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
tdx.setData(Right_et.getText().toString());
}
});
right_btn2 = (Button) view.findViewById(R.id.right_btn2);
right_btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
tdtl.setDataToLeft(Right_et.getText().toString());
}
});
}
public void setData(String str) {
Right_et.setText(str);
}
public interface TransDataX {
public void setData(String str);
}
public interface TransDataToLeft {
public void setDataToLeft(String str);
}
}
定义好之后,我们便可以在Activity中进行碎片绑定了,具体代码如下所示。
package com.skylake.fragment;
import com.skylake.fragment.LeftFragment.TransData;
import com.skylake.fragment.LeftFragment.TransDataToRight;
import com.skylake.fragment.RightFragment.TransDataToLeft;
import com.skylake.fragment.RightFragment.TransDataX;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity implements TransData,TransDataToRight,TransDataToLeft,TransDataX{
LeftFragment lFragment; //定义左侧碎片的对象
RightFragment rFragment; //定义右侧碎片的对象
EditText et1; //初始化一些输入和输出控件
Button btn1;
Button btn2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建Fragment对象,等待与Activity进行关联
lFragment = new LeftFragment();
rFragment = new RightFragment();
//关联操作,即将Fragment嵌入此Activity中
FragmentManager fManger = getFragmentManager();
FragmentTransaction ft = fManger.beginTransaction();
ft.replace(R.id.left_Fragment, lFragment);
ft.replace(R.id.right_Fragment, rFragment);
ft.commit(); //注意,我们动态绑定时,需要提交操作
et1 = (EditText) findViewById(R.id.et1);
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//当Fragment与Activity关联后,Fragment便成为此Activity中的一部分
//所以,我可以通过Fragment对象,来调用其内部的方法
lFragment.setData(et1.getText().toString());
}
});
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
rFragment.setData(et1.getText().toString());
}
});
}
/**
* 接口中的函数可以重复定义。多个接口实现了同一种功能,那么我们只需要定义一个公用的接口方法即可
* 实现Fragment与Activity通信时,定义的接口
*/
@Override
public void setData(String str) {
// TODO Auto-generated method stub
et1.setText(str);
}
@Override
public void setDataToRight(String str) {
// TODO Auto-generated method stub
rFragment.setData(str);
}
@Override
public void setDataToLeft(String str) {
// TODO Auto-generated method stub
lFragment.setData(str);
}
}
附上一张效果图吧~~
这里就大功告成啦~ 之后我会提供源码,供大家免费下载参考。
本文介绍了Android中的Fragment,包括它的作用、生命周期,并详细讲解了静态和动态Fragment的使用方法。重点探讨了Fragment之间的通信,提供了从Fragment到Activity以及反之的交互示例,帮助开发者掌握Fragment在UI设计和应用开发中的灵活运用。
1431

被折叠的 条评论
为什么被折叠?



