Fragment生命周期
- Fragment存在状态
活动状态:位于前台,用户可见,可以获得焦点 暂停状态:位于前台,依然可见,不能获得焦点 停止状态:不可见,失去焦点
- Fragment和宿主activity调用栈
I/debug (15575): FragmentActivity onCreate ----------------------添加Fragment---------------------- I/debug (15575): TestFragment onAttach //当Fragment与Activity发生关联时调用,只会被调用一次 I/debug (15575): TestFragment onCreate //创建Fragment时/当fragment和activity关联之后 被回调,只会被调用一次 I/debug (15575): TestFragment onCreateView //创建该Fragment的视图 I/debug (15575): TestFragment onViewCreated I/debug (15575): TestFragment onActivityCreated //当Activity的onCreate方法返回时调用 I/debug (15575): FragmentActivity onStart I/debug (15575): TestFragment onStart //启动Fragment时被回调 I/debug (15575): FragmentActivity onResume I/debug (15575): TestFragment onResume //恢复Fragment时被回调,onStart()方法后一定回调onResume() ----------------------运行状态---------------------- I/debug (15575): TestFragment onPause //暂停Fragment时被回调 ----------------------暂停状态---------------------- I/debug (15575): FragmentActivity onPause I/debug (15575): TestFragment onStop //停止Fragment时被回调 ----------------------停止状态---------------------- I/debug (15575): FragmentActivity onStop I/debug (15575): TestFragment onDestroyView //当该Fragment的视图被移除时调用,只会调用一次 I/debug (15575): TestFragment onDestroy //销毁Fragment时被回调,只会调用一次 I/debug (15575): TestFragment onDetach //将Fragment从Activity中删除,被替换完成时/和activity分离的时被回调,只会被调用一次 ----------------------销毁状态---------------------- I/debug (15575): FragmentActivity onDestroy 注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现
Fragment使用
- 静态添加Fragment
1、继承Fragment,重写onCreateView决定Fragemnt的布局 2、在Activity中声明此Fragment,和普通的View一样
// content.xml为该fragment布局文件 public class ContentFragment extends Fragment implements OnClickListener { private Button btn; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.content, container, false); btn = (Button) view.findViewById(R.id.btn); btn.setOnClickListener(this); return view; } @Override public void onClick(View view) {/* .. */ } }
<!-- 使用fragment--> <RelativeLayout 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" > <fragment android:id="@+id/id_fragment_title" android:name="com.example.test.TitleFragment" android:layout_width="fill_parent" android:layout_height="45dp" /> <include android:id="@+id/id_ly_bottombar" android:layout_width="fill_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" layout="@layout/bottombar" /> <FrameLayout android:id="@+id/id_content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@id/id_ly_bottombar" android:layout_below="@id/id_fragment_title" /> </RelativeLayout>
- 动态添加Fragment
// 动态添加fragment private void addFragment() { FourFragment four = new FourFragment(); FragmentManager manager = getFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.hide(this); transaction.add(R.id.id_content, four, "FOUR"); transaction.commit(); } //动态移除fragment private void replaceFragment() { OneFragment one = new OneFragment(); FragmentManager manager = getFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.replace(R.id.id_content, one); transaction.commit(); }
Fragment家族常用的API
- Fragment常用的三个类
android.app.Fragment:主要用于定义Fragment android.app.FragmentManager:主要用于在Activity中操作Fragment android.app.FragmentTransaction:保证一些列Fragment操作的原子性
- 常用方法
a、获取FragmentManage的方式 getFragmentManager() // v4中,getSupportFragmentManager
b、主要的操作都是FragmentTransaction的方法 FragmentTransaction transaction = fm.benginTransatcion();//开启一个事务 transaction.add() //往Activity中添加一个Fragment transaction.remove() //从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁 transaction.replace() //使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体 transaction.hide() //隐藏当前的Fragment,仅仅是设为不可见,并不会销毁 transaction.show() //显示之前隐藏的Fragment detach() //会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护 attach() //重建view视图,附加到UI上并显示 transaction.commit() //提交一个事务 transaction.commitAllowingStateLoss() //提交一个事务,允许丢失状态 transaction.addToBackStack(null) //管理fragment回退栈
注意:如果出现java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 是因为:commit方法一定要在Activity.onSaveInstance()之前调用
Fragment与Activity通信
- fragment与activity通信方式:
a、如果你Activity中包含自己管理的Fragment的引用,可以通过引用直接访问所有的Fragment的public方法 b、如果Activity中未保存任何Fragment的引用,那么没关系,每个Fragment都有一个唯一的TAG或者ID,可以通过getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行操作 c、在Fragment中可以通过getActivity得到当前绑定的Activity的实例,然后进行操作 注:如果在Fragment中需要Context,可以通过调用getActivity(),如果该Context需要在Activity被销毁后还存在,则使用getActivity().getApplicationContext()
- fragment与activity通信demo
//方法1:设置按钮监听的回调 public class OneFragment extends Fragment implements OnClickListener { private Button btn; public interface OneFragmentOnClickListener { public void onOneFragmentClick(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.one, container, false); btn = (Button) view.findViewById(R.id.btn); btn.setOnClickListener(this); return view; } @Override public void onClick(View view) { if (getActivity() instanceof OneFragmentOnClickListener) { ((OneFragmentOnClickListener) getActivity()).onOneFragmentClick(); } } } //方法2: public class TwoFragment extends Fragment implements View.OnClickListener { private TwoFragmentOnClickListener listener; public interface TwoFragmentOnClickListener { public void onTwoFragmentClick(); } public void setListener (TwoFragmentOnClickListener listener) { this.listener = listener; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.two, container, false); Button button = (Button) view.findViewById(R.id.btn); button.setOnClickListener(this); return view; } @Override public void onClick(View view) { if (listener != null) { listener.onTwoFragmentClick(); } } }
//Activity public class FragmentActivity extends Activity implements OneFragmentOnClickListener, TwoFragmentOnClickListener { private TwoFragment two; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment); if (savedInstanceState == null) { setDefaultFragment(); } two = new TwoFragment(); two.setListener(this); } @Override public void onOneFragmentClick() { //do something } @Override public void onTwoFragmentClick() { //do something } }
Fragment设置选项菜单
- 步骤
a、在Fragment的onCreate中调用 setHasOptionsMenu(true) b、然后在Fragment子类中实现onCreateOptionsMenu c、如果希望在Fragment中处理MenuItem的点击,也可以实现onOptionsItemSelected;Activity也可以直接处理该MenuItem的点击事件
- Demo
public class OneFragment extends Fragment implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.one, container, false); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // fragment_menu为定义的菜单 inflater.inflate(R.menu.fragment_menu, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // do something } return true; } }