Fragment的使用

来源:互联网 发布:java培训机构比较好 编辑:程序博客网 时间:2024/06/11 06:44

1.Fragment的设计哲学

Android在3.0中引入了Fragments的概念,主要目的是用在大屏幕设备上,支持更加动态和灵活的UI设计,例如平板电脑上,它的屏幕比手机大很多,会存在许多需要交互的UI组件,这时我们就需要用到Fragment了。从下图中我们可以看到Fragment的实际应用。


Fragment你的应用中应当是一个模块化和可重用的组件,因为Fragment定义了自己的布局,以及通过使用自己的生命周期回调方法定义了自己的行为,可以Fragment包含到多个Activity


2.Fragment的知识概要

Fragment与iActivity之间的关系:

(1)     Fragment可以作为Activity界面的一部分组成出现;

(2)     可以在一个Activity中同时出现多个Fragment,并且一个Fragment也可以在多个Activity中使用;

(3)     Activity运行过程中,可以添加、移除或替换Fragment

(4)     Fragment可以响应自己的输入事件,并且有自己的生命周期,它们的生命周期会受宿主Activity的生命周期影响

onCreatView()方法:

       Fragment第一次绘制它的用户界面的时候,系统会调用此方法,为了绘制FragmentUI,此方法必须返回一个ViewFragment要显示的视图),如果不显示UI,返回null即可。

3.Fragment的加载


3.1. 静态加载

Activitylayout文件中声明Fragment,需要特别注意的是<fragment>中的androidname属性(name属性的值是Fragment所在类的包名)指定了在layout中实例化的Fragment类。标识Fragment的方法:

androidid属性提供一个唯一的ID

androidtag属性提供一个唯一字符串;

静态加载实例:androidstdio为运行环境。

2为整个实例的运行界面与工程目录中主要代码的之间的对应关系。


对页面布局的重点描述:

MainActivity.Java为主窗口,其布局为main.xml,点击主窗口里的“静态加载”后跳到了窗口MainActivity2.java(盛放fragment的activity),其布局为main2.xml文件,main2.xml里有如下代码:


该代码是用于声明Fragment的。MyFragment.java是上面代码声明Fragment的实现类,fragment.xml文件为MyFragment.java的布局,MyFragment.java的重要代码:


为了绘制fragment的UI,在调用onCreateView方法时,需要将fragment的布局文件fragment.xml转化为一个View对象。

还有个重点是:就是按钮“改变”的点击效果,“改变”按钮控件是放置布局fragment.xml里的,但其的点击事件是在MainActivity.java中实现的,主要目的是为了说明Activity可以获取到寄宿在它里面的fragment的布局的控件,并可以操作其控件的属性。

3.2. 动态加载

撰写代码将Fragment添加到一个Avtivity中,add():添加一个Fragment(指定要添加的的Fragment和插入的view),与此类似的还有remove()、替换replace()。

         处理Fragment事务:根据用户的交互情况,对Fragment进行添加、移除、替换,以及执行其它动作,提交给Activity的每一套变化被称作一个事务。

//获取管理者
FragmentManager fragmentManager = getFragmentManager();
/创建事务FragmentTransaction beginTransaction = fragmentManager.beginTransaction();

每一个事务都是同时执行一套变化,可以在一个事务中可以设置你所有想执行的变化,包括add()、remove()、replace()、然后提交给activity,必须调用commit方法。如果用户通过按下back键返回到前一个Fragment状态,调用commit之前可以加入addToBackStack()方法

动态加载实例:

效果图:


MainActivity.java

//点击动态加载时,所触发的事件
case R.id.second: {

//要添加的Fragment

MyFragment2 fragment2=newMyFragment2();

//获得Fragment的管理器
         
FragmentManager fragmentManager = getFragmentManager();
          //利用管理器开启事务

FragmentTransaction beginTransaction = fragmentManager.beginTransaction();

//往MainActivity.java的布局main.xml里id名为frame的控件中添加Fragment
         
beginTransaction.add(R.id.frame,fragment2);

//返回键的效果
          beginTransaction.addToBackStack(null);
          beginTransaction.commit();
   break;
}

















4 .Fragment的生命周期

观察生命周期的步骤:启动Fragment——>屏幕锁屏——>屏幕解锁——>
切换到其他的Fragment——>回到桌面——>回到应用——>退出Fragment

每一步会调用的方法:

(1)      启动FragmentFragment1---onAttach()       Fragment1---onCreate()

Fragment1---onCreateView()         Fragment1---onActivityCreated()

Fragment1---onStart()               Fragment1---onResume()

(2)      屏幕锁屏:Fragment1---onPause()         Fragment1---onStop()

(3)      屏幕解锁:Fragment1---onStart()          Fragment1---onResume()

(4)      切换到其他的FragmentFragment1---onPause()           Fragment1---onStop()

Fragment1---onDestroyView()            Fragment1---onDestroy()

Fragment1---onDetach()                Fragment2---onAttach()

Fragment2---onCreate()                Fragment2---onCreateView()

Fragment2---onActivityCreated()         Fragment2---onStart()

Fragment2---onResume()

(5)      回到桌面:Fragment2---onPause()          Fragment2---onStop()

(6)      回到应用:Fragment2---onStart()           Fragment2---onResume()

(7)      退出FragmentFragment2---onPause()      Fragment2---onStop()

Fragment2---onDestroyView()             Fragment2---onDestroy()

Fragment2---onDetach()

onCreateView:每次创建都会绘制FragmentView组件时回调该方法;

onAttach: Fragment被添加到Activity时候会回调这个方法,并且只调用一次;

onCreate:创建Fragment时会回调,只会调用一次;

onActivityCreatedFragment所在的Activty启动完成后调用;

onStart : 启动Fragment

onResume : 恢复Fragment时会被回调,调用onStart()方法后面一定会调用onResume()方法;

onPause: 暂停Fragment

onStop :停止Fragment

onDestroyView(): 销毁Fragment所包含的View组件时;

onDestroy销毁Fragment时会被回调;

onDetach : FragmentActivity中删除时会回调该方法,并且这个方法只会调用一次;

实例:

点击生命周期后的效果图:


MainActivity.java

//点击生命周期
case R.id.thrid: {
         
Intent intent=new Intent(MainActivity.this,MainActivity3.class);
         
startActivity(intent);
   break;
}

 

MainActivity3.java

public class MainActivity3extendsActivity {

  
private Buttonbutton;
  
private Fragmentfrag;
  
private boolean flag=true;
  

   @Override
  
protected void onCreate(Bundle savedInstanceState) {
     
// TODO Auto-generated method stub
     
super
.onCreate(savedInstanceState);
     
setContentView(R.layout.main3);

//一开始显示的是MyFragment3
     
init();

//点击按钮可以切换到MyFragment4,
     
button = (Button) findViewById(R.id.button);
     
button.setOnClickListener(newOnClickListener() {

        
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
        
@Override
        
public void onClick(View v) {
           
// TODO Auto-generated method stub
           
FragmentManager fragmentManager = getFragmentManager();
           
FragmentTransaction beginTransaction = fragmentManager
                  .beginTransaction();
           
            if (flag) {
              
MyFragment4 frag4=new MyFragment4();
              
beginTransaction.replace(R.id.layout, frag4);
              
flag=false;

           
} else {
 
             MyFragment3 frag3=new MyFragment3();
              
beginTransaction.replace(R.id.layout, frag3);
              
flag=true;
           
}
            beginTransaction.commit();
         }
      });
   }

   @TargetApi(Build.VERSION_CODES.HONEYCOMB)
  
private void init() {
     
// TODO Auto-generated method stub
     
FragmentManager fragmentManager = getFragmentManager();
     
FragmentTransaction beginTransaction = fragmentManager
            .beginTransaction();
      MyFragment3 frag3 = new MyFragment3();
     
beginTransaction.add(R.id.layout,frag3);
     
beginTransaction.commit();
   }
}

5. Fragment的传值通信

Activity-----Fragment:在Activity中创建Bundle数据包,并调用FragmentsetArguments(Bundle bundle)方法。

Fragment-----Activity:需要在Fragment中定义一个内部回调接口再让包含该FragmentActivity实现该回调接口,这样Fragment可调用该回调方法将数据传递给Activity

点击传值通信的效果图:


MainActivity4.java
public class MainActivity4 extends Activity implements MyFragment5.MyListener {     private EditText editext;   private Button send;     @TargetApi(Build.VERSION_CODES.HONEYCOMB)   @Override   protected void onCreate(Bundle savedInstanceState) {      // TODO Auto-generated method stub      super.onCreate(savedInstanceState);      setContentView(R.layout.main4);      editext = (EditText) findViewById(R.id.editText);      send = (Button) findViewById(R.id.send);      send.setOnClickListener(new OnClickListener() {           @TargetApi(Build.VERSION_CODES.HONEYCOMB)         @Override         public void onClick(View v) {            // TODO Auto-generated method stub            String text = editext.getText().toString();            MyFragment5 fragment5 = new MyFragment5();            Bundle bundle = new Bundle();            bundle.putString("name", text);            fragment5.setArguments(bundle);            FragmentManager fragmentManager = getFragmentManager();            FragmentTransaction beginTransaction = fragmentManager                  .beginTransaction();            beginTransaction.add(R.id.layout, fragment5, "fragment5");            beginTransaction.commit();            Toast.makeText(MainActivity4.this, "向Fragment发送数据" + text,                  Toast.LENGTH_SHORT).show();         }      });         //Fragment静态传值
      FragmentManager fragmentManager = getFragmentManager();      Fragment findFragmentById = fragmentManager.findFragmentById(R.id.frag);        MyFragment frag=(MyFragment) findFragmentById;        frag.setAaa("fragment静态传值");   }     @Override   public void thank(String code) {      // TODO Auto-generated method stub      Toast.makeText(MainActivity4.this, "已成功接收到" + code + ",客气了!",            Toast.LENGTH_SHORT).show();   }  }

 

MyFragment5.java
public class MyFragment5 extends Fragment {     private String code="Thank you,Activity!";      public MyListener listener;   public interface MyListener   {      public void thank(String code);   }      @Override   public void onAttach(Activity activity) {      // TODO Auto-generated method stub       listener=(MyListener) activity;      super.onAttach(activity);   }   @Override   public View onCreateView(LayoutInflater inflater, ViewGroup container,         Bundle savedInstanceState) {      // TODO Auto-generated method stub      View view = inflater.inflate(R.layout.fragment2, container, false);      TextView tv = (TextView) view.findViewById(R.id.text);      String text=getArguments().get("name")+"";        tv.setText(text);      Toast.makeText(getActivity(), "已成功接收到"+text, Toast.LENGTH_SHORT).show();      Toast.makeText(getActivity(), "向Activity发送"+code, Toast.LENGTH_SHORT).show();      listener.thank(code);      return view;   }}

 

Main4.xml
<?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/layout"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >      <EditText        android:id="@+id/editText"        android:layout_width="match_parent"        android:layout_height="wrap_content" />      <Button        android:id="@+id/send"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="发送" />   <!--用于静态传值的-->    <fragment         android:id="@+id/frag"        android:name="com.imooc.fragment.MyFragment"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        />  </LinearLayout>
0 0
原创粉丝点击