如果同一ui中使用了多个fragment如何优化?
先上代码
public class MainActivity extends FragmentActivity {
TabHost tHost;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取主布局中的TabHost,找到id
tHost = (TabHost) findViewById(android.R.id.tabhost);
tHost.setup();
// 设置Tabhost的监听器
/**
* Defining Tab Change Listener event. This is invoked when tab is
* changed
*/
TabHost.OnTabChangeListener tabChangeListener = new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
// 定义fragmentManager
FragmentManager fm = getFragmentManager();
// 获取标签,强转成自定义的fragment类型
AndroidFragment androidFragment = (AndroidFragment) fm
.findFragmentByTag("android");
AppleFragment appleFragment = (AppleFragment) fm
.findFragmentByTag("apple");
// 启动fragment事物
FragmentTransaction ft = fm.beginTransaction();
// 判断获取的事物标签非空,重新連接fragment
if (androidFragment != null)
ft.detach(androidFragment);
if (appleFragment != null)
ft.detach(appleFragment);
// 选中标签时执行,判斷非空時
if (tabId.equalsIgnoreCase("android")) {
if (androidFragment == null) {
// 向布局文件中传入自定义fragment,這裡add和replace是一樣的
ft.add(R.id.realtabcontent, new AndroidFragment(),
"android");
} else {
//如果已經啟動,則把它帶到前局顯示
ft.attach(androidFragment);
}
} else {
//如果碎片对象为空,则替换布局中的碎片
if (appleFragment == null) {
/**
* Create AppleFragment and adding to
* fragmenttransaction
*/
ft.add(R.id.realtabcontent, new AppleFragment(),
"apple");
} else {
//不为空,则说明已经加载了
ft.attach(appleFragment);
}
}
ft.commit();
}
};
/** 设置标签的监听 */
tHost.setOnTabChangedListener(tabChangeListener);
/** 设置android便签的标题,图标*/
TabHost.TabSpec tSpecAndroid = tHost.newTabSpec("android");
tSpecAndroid.setIndicator("Android",
getResources().getDrawable(R.drawable.ic_launcher));
tSpecAndroid.setContent(new KankanTabContent(getBaseContext()));
tHost.addTab(tSpecAndroid);
/** 设置apple便签的标题,图标*/
TabHost.TabSpec tSpecApple = tHost.newTabSpec("apple");
tSpecApple.setIndicator("Apple",
getResources().getDrawable(R.drawable.ic_launcher));
tSpecApple.setContent(new KankanTabContent(getBaseContext()));
tHost.addTab(tSpecApple);
}
其中自定义了android余额apple两个自定义fragment类,然后冲写了tabContent方法。
注意黄色部分,这里的attach,与detach干什么用呢?找了一些源代码。
1.fragmentTransact 中的add实际就是replace,只是多了一个Tag
2.类似余额activity的声明周期,为了提高内存利用率,使用add()加入fragment时
将触发onAttach(),使用attach()不会触发onAttach()
使用replace()替换后会将之前的fragment的view从viewtree中删除。
触发顺序:
detach()->onPause()->onStop()->onDestroyView()
attach()->onCreateView()->onActivityCreated()->onStart()->onResume()。
使用hide()方法只是隐藏了fragment的view并没有将view从viewtree中删除,随后可用show()方法将view设置为显示,
而使用detach()会将view从viewtree中删除,和remove()不同,此时fragment的状态依然保持着,
在使用attach()时会再次调用onCreateView()来重绘视图。注意使用detach()后fragment.isAdded()方法
将返回false,在使用attach()还原fragment后isAdded()会依然返回false(需要再次确认)。
执行detach()和replace()后要还原视图的话, 可以在相应的fragment中保持相应的view,
并在onCreateView()方法中通过view的parent的removeView()方法将view和parent的关联删除后返回。
当然关联删除后,systemgc就会执行垃圾回收了。