Fragment详解

鸿洋大神

一、Fragment为什么会被称为第五大组件

一、Fragment为什么会被称为第五大组件

Fragment的中文含义是碎片,在之前安卓开发是,用户界面的切换全部使用activity的切换,这就造成了整个应用使用起来速度较慢,而且很占内存,因为activity是重量级的组件,在应用程序内部使用很不方便。于是出现了Fragment来解决这样的问题。Fragment是一种便捷的、轻量级的、基于activity的组件,所谓基于activity,就是必须有activity作为容器,Fragment才可以生存。另外,Fragment 可以动态的添加和删除。所以说Fragment是一种非常方便开发的组件 。

二、Fragment加载到Activity中的两种方式

1、在Activity布局文件的内部声明Fragment。

<fragment
name用于设置Fragment子类的类完整路径(全类名)
android:name="com.example.news.MyFragment"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />

2、使用FramLayout通过代码添加要显示的Fragment

`FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();`

使用FrameLayout的优点:

1、通过在布局中添加显示Fragment与通过在代码中添加显示Fragment有没有什么区别??
通过在布局中添加fragment标签显示的Fragment对象永远无法被替换以及删除。

2、在通过代码添加Fragment的时候,使用FrameLayout与其余的Layout有什么区别??有什么优点??

a.假设Fragment中设置的布局宽高以及布局控件中设置的宽高都设置match_parent,添加到FrameLayout中的Fragment可以实现match_parent的特点,但是添加到LinearLayout中的Fragment不行

b. 当通过add方法多次添加要显示的Fragemnt对象时,如果使用FrameLayout,那么多个Fragment对象之间是重叠覆盖效果,而LinearLayout是垂直或者水平排列效果

三、FragmentPagerAdapter和FragmentStatePagerAdapter的区别

主要区别就在与对于fragment是否销毁:
FragmentPagerAdapter:对于不再需要的fragment,选择调用detach方法,仅销毁视图,并不会销毁fragment实例。

这里写图片描述

FragmentStatePagerAdapter:会销毁不再需要的fragment,当当前事务提交以后,会彻底的将fragmeng从当前Activity的FragmentManager中移除,state标明,销毁时,会将其onSaveInstanceState(Bundle outState)中的bundle信息保存下来,当用户切换回来,可以通过该bundle恢复生成新的fragment,也就是说,你可以在onSaveInstanceState(Bundle outState)方法中保存一些数据,在onCreate中进行恢复创建。
这里写图片描述

如上所说,使用FragmentStatePagerAdapter当然更省内存,但是销毁新建也是需要时间的。一般情况下,如果你是制作主页面,就3、4个Tab,那么可以选择使用FragmentPagerAdapter,如果你是用于ViewPager展示数量特别多的条目时,那么建议使用FragmentStatePagerAdapter。

二、Fragment的生命周期

这里写图片描述

Fragment和Activity生命周期的绑定

这里写图片描述

三、Fragment之间的通信

一、在Activity向Fragment中传值

1、要传的值 放到Bundle对象里

2、通过创建传递封Fragment 将bundle对象 通过 setArguments()传递到fragment

3、Fragment中 通过getArguments() 得到 bundle对象 就能得到里面的值

二、在Fragment向Activity中传值

1.在Fragment中写一个回调接口

2.在activity中实现这个回调接口

3,在Fragment中onAttach 方法中得到activity中实现好的 实例化接口对象

4,用接口的对象 进行传值

public class Fragmen1 extends Fragment{  
    private Button btn1;  
    private EditText et1;  
    CallBackValue callBackValue;  

    /** 
     * fragment与activity产生关联是  回调这个方法  
     */  
    @Override  
    public void onAttach(Activity activity) {  
        // TODO Auto-generated method stub  
        super.onAttach(activity);  
        //当前fragment从activity重写了回调接口  得到接口的实例化对象  
        callBackValue =(CallBackValue) getActivity();  
    }  


    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        View view = inflater.inflate(R.layout.fragment_layout1, container, false);  
         btn1 = (Button) view.findViewById(R.id.btn1);  
         et1 = (EditText) view.findViewById(R.id.et1);  
         btn1.setOnClickListener(new OnClickListener() {  

            @Override  
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                String strValue = et1.getText().toString().trim();  
                callBackValue.SendMessageValue(strValue);  

            }  
        });  

        return view;  
    }  
    //定义一个回调接口  
    public interface CallBackValue{  
        public void SendMessageValue(String strValue);  
    }  
}

Activity代码:

public class MainActivity extends Activity implements CallBackValue{  

    private TextView tv1;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  

        tv1 = (TextView) findViewById(R.id.tv1);  

        FragmentManager manager = getFragmentManager();  
        FragmentTransaction transaction = manager.beginTransaction();  

        transaction.add(R.id.contents, new Fragmen1());  
        transaction.commit();  

    }  
    //要获取的值  就是这个参数的值  
    @Override  
    public void SendMessageValue(String strValue) {  
        // TODO Auto-generated method stub  
        tv1.setText(strValue);  
    } 

三、在Fragment向Fragment中传值

1.在FragmentA中通过接口回调的方式,将数据传递给当前FragmentA所在的Activity中

2.在Activity的接口重写方法中,接收到传递过来的数据后,通过BFragment对象调用BFragment对象中的自定义方法,将数据再从页面传递给B对象

四、Fragment的管理器:FragmentManager

1、FragmentManager是抽象类,定义了很多方法。具体的实现,在于它的内部类

public abstract class FragmentManager

2、FragmentManager的操作,大部分都在FragmentManagerImpl中。

final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章