[置顶] Fragment,FragmentManager, FragmentTransaction详解

Fragment是3.0引入的新组件,在3.0之前需要引入v4包的Fragment进行向下兼容,在项目中会频繁用到。

先说下3.0的Fragment用法。

其中,Fragment的生命周期就不多说了,首先构建Fragment 的View对象。

@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View v = inflater.inflate(R.layout.fragment02, null);
		return v;
	}

然后在Activity中显示目标Fragment。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        fg3 = new Fragment03();
    	//获取fragment管理器
    	FragmentManager fm = getFragmentManager();
    	//打开事务
    	FragmentTransaction ft = fm.beginTransaction();
    	//把内容显示至帧布局
    	ft.replace(R.id.fl, fg3);
    	//提交
    	ft.commit();
    }


需要注意的是Fragment只能替换Activity中的FrameLayout。

<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"
    tools:context=".MainActivity" 
    android:orientation="horizontal"
    >

   
	<FrameLayout 
	    android:id="@+id/fl"
	    android:layout_weight="1"
	    android:layout_width="0dp"
	    android:layout_height="match_parent"
	    ></FrameLayout>
	
	 <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="fragment01"
            android:onClick="click1"
            />
        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="fragment02"
            android:onClick="click2"
            />
        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="fragment03"
            android:onClick="click3"
            />
    </LinearLayout>
</LinearLayout>


之后我们说下Fragment 的向下兼容模式:

首先,我们要先导入系统自带的V4包。

package com.itheima.supportfragment;

import android.os.Bundle;
import android.app.Activity;
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.View;

public class MainActivity extends FragmentActivity {

    private Fragment03 fg3;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        fg3 = new Fragment03();
    	//获取fragment管理器
    	FragmentManager fm = getSupportFragmentManager();
    	//打开事务
    	FragmentTransaction ft = fm.beginTransaction();
    	//把内容显示至帧布局
    	ft.replace(R.id.fl, fg3);
    	//提交
    	ft.commit();
    }
}

与上者使用方法大体相同,都是替换Activity中的FrameLayout布局。

最后说下Activity与Fragment之间数据的传递。

@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View v = inflater.inflate(R.layout.fragment01, null);
		
		final EditText et = (EditText) v.findViewById(R.id.et);
		Button bt = (Button) v.findViewById(R.id.bt);
		bt.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				String text = et.getText().toString();
				//把数据传递给activity
				((MainActivity)getActivity()).setText(text);
				
			}
		});
		return v;
	}
Fragment向Activity传递数据时,直接调用getActivity()获取Activity的对象。

public void click4(View v){
    	
    	String text = et_main.getText().toString();
    	
    	//传递数据
    	fg3.setText(text);
    }
Activity向Fragment传递数据时,先new一个Fragment即可。

但是一般Fragment与Activity之间最好利用回调接口的方式进行数据传递。这样做的好处是利于Fragment的重用性。

public static class FragmentA extends ListFragment{
   ...
   //Container Activity must implement this interface
   public interface OnArticleSelectedListener{
       public void onArticleSelected(Uri articleUri);
   }
   ...
}
public static class FragmentA extends ListFragment{
   OnArticleSelectedListener mListener;
   ...
   @Override
   public void onAttach(Activity activity){
       super.onAttach(activity);
       try{
           mListener =(OnArticleSelectedListener)activity;
       }catch(ClassCastException e){
           throw new ClassCastException(activity.toString()+"must implement OnArticleSelectedListener");
       }
   }
   ...
}

如果 activity 没有实现那个接口, fragment 抛出 ClassCastException 异常。如果成功了, mListener 成员变量保存 OnArticleSelectedListener 的实例。于是 fragmentA 就可以调用 mListener 的方法来与 activity 共享事件。例如,如果 fragmentA 是一个 ListFragment ,每次选中列表的一项时,就会调用 fragmentA onListItemClick() 方法,在这个方法中调用 onArticleSelected() 来与 activity 共享事件,如下:

public static class FragmentA extends ListFragment{
   OnArticleSelectedListener mListener;
   ...
   @Override
   public void onListItemClick(ListView l,View v,int position,long id){
       //Append the clicked item's row ID with the content provider Uri
       Uri noteUri =ContentUris.withAppendedId(ArticleColumns.CONTENT_URI,id);
       //Send the event and Uri to the host activity
       mListener.onArticleSelected(noteUri);
   }
   ...
}


FragmentManager用来管理Fragment的,利用Activity的getFragmentManager()取得它的实例.

FragmentManager可以做如下一些事情:

1、使用findFragmentById() (用于在activity layout中提供一个UI的fragment)或findFragmentByTag()(适用于有或没有UI的fragment)获取activity中存在的fragment 

2、将fragment从后台堆栈中弹出, 使用 popBackStack() 

3、使用addOnBackStackChangeListener()注册一个监听后台堆栈变化的listener.

FragmentTransaction是对Fragment进行添加,替换,移除等操作的。
在使用add(),replace(),remove()时可以动态的给每一个Fragment添加一个标签,下次方便FragmentManager通过tag标签进行查找。最后记得ft.commit();

  
  
  
  
当执行一个移除fragment的事务时, 如果没有调用 addToBackStack(), 那么当事务提交后, 那个fragment会被销毁,并且用户不能导航回到它. 有鉴于此, 当移除一个fragment时,如果调用了 addToBackStack(), 那么fragment会被停止, 如果用户导航回来,它将会被恢复.////我认为是重要的, 
以上的话,可以理解,remove后,加到堆栈后。按返回还是可以返回到之前的fragment。
fragment的显示和隐藏可以用FragmentTransaction的show 或是hide来实现,
 ft.show(fragment);  ft.hide(fragment);









你可能感兴趣的:([置顶] Fragment,FragmentManager, FragmentTransaction详解)