Fragment是在Android 3.0 (API level 11)开始引入的,它能让你的app在现有基础上性能大幅度提高,并且占用内存降低,同样的界面Activity占用内存比Fragment要多,响应速度Fragment比Activty在中低端手机上快了很多,甚至能达到好几倍,同时给大屏幕(如平板电脑)上更加动态和灵活的 UI 设计提供支持.
一、Fragment的生命周期
Fragment表示Activity中的行为或用户界面部分,其生命周期直接受宿主activity生命周期的影响。下图可以很直观反映出两者的关系:
Fragment比Activity多出的几个生命周期回调方法:
onAttach(Activity):
called once the fragment is associated with its activity.(当Fragment和Activity相关联调用
onCreateView(LayoutInflater, ViewGroup, Bundle)
creates and returns the view hierarchy associated with the fragment.(创建Fragment的视图
onActivityCreated(Bundle)
tells the fragment that its activity has completed its own Activity.onCreate(). (当Activity.onCreate()完成时调用
onDestroyView()
allows the fragment to clean up resources associated with its View.
onDetach()
called immediately prior to the fragment no longer being associated with its activity
二、Fragment 的使用
静态使用
把Fragment当做普通的控件写入Activity的布局文件中,用布局文件调用Fragment,这里不再展开
动态使用
Fragment动态使用主要是动态添加,更新,删除.
在activity的布局文件中添加一个FrameLayout,作为fragment需要放入的ViewGroup
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version="1.0" encoding="utf-8"?> <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" tools:context="net.december1900.test.MainActivity"> <FrameLayout android:id="@+id/content_layout" android:layout_width="match_parent" android:layout_height="match_parent"/>
</RelativeLayout>
|
fragment和主activity
1 2 3 4 5 6 7 8 9
| public class MainFragment extends Fragment{
@Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_main,container,false); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class MainActivity extends AppCompatActivity {
private MainFragment mMainFragment;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); showFragment(); }
private void showFragment(){ FragmentManager manager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = manager.beginTransaction(); mMainFragment = new MainFragment(); fragmentTransaction.replace(R.id.content_layout,mMainFragment); fragmentTransaction.commit(); } }
|
显示
Fragment常用的类
android.app.FragmentManager
获取方式:getSupportFragmentManager();
android.app.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
transatcion.commit()
总结起来:
如果你希望保留用户操作的面板,可以使用show(),hide()。其实是让Fragment的View setVisibility(true还是false),不会调用生命周期
如果你不希望保留用户操作,可以使用replace()。其会销毁视图,即调用onDestoryView、onCreateView等一系列生命周期
三、管理Fragment的回退栈
我们可以通过Activity维护一个回退栈来保存每次Fragment事务发生的变化。如果将Fragment任务添加到回退栈,当用户点击后退按钮时,将看到上一次的保存的Fragment。一旦Fragment完全从后退栈中弹出,用户再次点击后退键,则会退出当前Activity。
添加一个Fragment事务到回退栈:
FragmentTransaction.addToBackStack(String)
主activity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class MainActivity extends AppCompatActivity {
private MainFragment mMainFragment;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); showFragment("MainFragment"); }
private void showFragment(String tag) { FragmentManager manager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = manager.beginTransaction(); mMainFragment = new MainFragment(); fragmentTransaction.add(R.id.content_layout, mMainFragment, tag); fragmentTransaction.addToBackStack(tag); fragmentTransaction.commit();
}
}
|
MainFragment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class MainFragment extends Fragment {
@BindView(R.id.btn_main) Button mBtnMain;
@Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_main, container, false); ButterKnife.bind(this, view); return view; }
@OnClick(R.id.btn_main) public void onViewClicked() {
showFragment("SecondFragment"); }
private void showFragment(String tag) { SecondFragment secondFragment = new SecondFragment(); FragmentManager manager = getFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.replace(R.id.content_layout, secondFragment, tag); transaction.addToBackStack(tag); transaction.commit();
} }
|
SecondFragment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class SecondFragment extends Fragment {
@BindView(R.id.btn_second) Button mBtnSecond;
@Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_second, container, false); ButterKnife.bind(this, view); return view; }
@OnClick(R.id.btn_second) public void onViewClicked() { showFragment("ThirdFragment"); }
private void showFragment(String tag) { ThirdFragment thirdFragment = new ThirdFragment(); FragmentManager manager = getFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.add(R.id.content_layout, thirdFragment, tag); transaction.addToBackStack(tag); transaction.commit(); } }
|
显示
总体来说,我们调用addToBackStack(tag);将当前的事务添加到了回退栈,所以MainFragment实例不会被销毁,但是视图层次依然会被销毁,即会调用onDestoryView和onCreateView,但是使用add()方法的SecondFragment视图层依然存在