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; }
@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(); }
<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>
首先,我们要先导入系统自带的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"); } } ... }
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可以做如下一些事情:
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);