提笔犯怵,好久没总结干货了,知识普遍都是碎片化的,记录在云笔记里的比较多和杂。
最近项目用了BottomBar这个开源控件,狂拽炫酷吊炸天,视觉效果很好,还支持behavior,与NestedScrollView结合可以下拉隐藏,上滑显示,上个图。
以上都不是重点————分割———埋个雷–使用fragmentmanager管理Fragment的生命周期方法——
项目要使用fragment,fragment切换不需要滑动切换,当然可以不用viewpager了,也就不需要fragmentPagerAdapter了(纯手打,如果单词错了勿怪),使用fragmentmanager+frameLayout动态显示隐藏fragment,Activity代码在后面,先让我啰嗦完:
上一个项目使用的TabHost+FrameLayout+Fragment,对于Fragment的生命周期方法的执行有了一定的认识,在BaseFragment中做了详细记录,如下:
public abstract class BaseFragment extends Fragment {
protected View rootView;
public Context mContext;
private boolean isCacheView=true;//是否缓存view
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isCacheView = setISCacheView();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (null!=rootView && isCacheView) {
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null) {
parent.removeView(rootView);
}
}else {
rootView = loadView(inflater);
}
bindView(rootView);
return rootView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
LogUtils.w(this.getClass().getSimpleName()+"onViewCreated");
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//每次切换fragment都会调用
LogUtils.w(this.getClass().getSimpleName()+"onActivityCreated");
}
@Override
public void onDestroyView() {
super.onDestroyView();
LogUtils.w(this.getClass().getSimpleName()+"onDestroyView");
}
/**
* 子类必须实现,载入自己的布局文件
* 如果缓存view,则只会执行一次
* @param inflater
* @return
*/
protected abstract View loadView(LayoutInflater inflater);
/**
* 子类必须实现,每次显示fragment时更新view
* 不管缓存与否,每次都执行
* @param rootView
*/
protected abstract void bindView(View rootView);
public boolean setISCacheView(){
return true;
}
public View getView(){
return rootView;
}
/**
* 在该方法中才可以使用mContext
*/
public void loadData(){};
/**
* 修改titleBar标题
* @param s
*/
public void setActivityTitle(String s){
if (null!=mContext){
BaseActivity activity = (BaseActivity) mContext;
activity.setTitle(s);
}
}
public void showProgressBar(){
if (null!=mContext){
MainActivity activity = (MainActivity) mContext;
activity.showProgress();
}
}
public void hideProgressBar(){
if (null!=mContext){
MainActivity activity = (MainActivity) mContext;
activity.hideProgress();
}
}
public void increaseProgress(){
if (null!=mContext){
MainActivity activity = (MainActivity) mContext;
activity.increateProgress();
}
}
}
当前项目无脑的把上个项目的基类拷贝过来,想当然的以为使用FragmentManager自己管理fragment,其生命周期方法也一样,然后我在bindView(View rootView)方法里改变MainActivity内toolBar的标题,实现切换fragment时,标题也切换。但是并没有,切换fragment时,周期方法没有如期回调。
这里讲的比我清楚http://blog.csdn.net/a910626/article/details/46016887不同的是我fragment使用了tag标记,添加前判断是否存在,存在则弹出,不会重复创建。
public class MainActivity extends BaseActivity implements OnTabSelectListener {
private FragmentManager fragmentManager;
private ArrayList<String> fragmentTags;
private int currIndex;
private static final String CURR_INDEX = "currIndex";
private BottomBar bottomBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getSupportFragmentManager();
initToolBar();
initData(savedInstanceState);
initView();
}
private void initView() {
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
bottomBar = (BottomBar) findViewById(R.id.bottomBar);
bottomBar.setOnTabSelectListener(this);
bottomBar.setTabSelectionInterceptor(new TabSelectionInterceptor() {
@Override
public boolean shouldInterceptTabSelection(@IdRes int oldTabId, @IdRes int newTabId) {
if (oldTabId == R.id.tab_favorites&&newTabId==R.id.tab_friends)
return true;
return false;
}
});
showFragment();
}
private void initData(Bundle savedInstanceState) {
fragmentTags = new ArrayList<>(Arrays.asList("HomeFragment", "ImFragment", "InterestFragment"));
currIndex = 0;
if(savedInstanceState != null) {
currIndex = savedInstanceState.getInt(CURR_INDEX);
hideSavedFragment();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(CURR_INDEX, currIndex);
}
private void hideSavedFragment() {
Fragment fragment = fragmentManager.findFragmentByTag(fragmentTags.get(currIndex));
if(fragment != null) {
fragmentManager.beginTransaction().hide(fragment).commit();
}
}
private void showFragment() {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment fragment = fragmentManager.findFragmentByTag(fragmentTags.get(currIndex));
if(fragment == null) {
fragment = FragmentFactory.createFragment(currIndex);
}
for (int i = 0; i < fragmentTags.size(); i++) {
Fragment f = fragmentManager.findFragmentByTag(fragmentTags.get(i));
if(f != null && f.isAdded()) {
fragmentTransaction.hide(f);
}
}
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
fragmentTransaction.add(R.id.fragment_container, fragment, fragmentTags.get(currIndex));
}
fragmentTransaction.commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
}
@Override
public String returnToolBarTitle() {
return "测试";
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onTabSelected(@IdRes int tabId) {
switch (tabId){
case R.id.tab_favorites:
currIndex = 0;
BottomBarTab nearby = bottomBar.getTabWithId(R.id.tab_nearby);
nearby.setBadgeCount(5);
break;
case R.id.tab_nearby:
currIndex = 1;
break;
case R.id.tab_friends:
currIndex = 2;
break;
default:
break;
}
showFragment();
}
}
好人做到底,布局文件
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.vmove.ecg.activity.MainActivity">
<include
layout="@layout/include_toolbar"/>
<FrameLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="@color/gray_white"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<com.roughike.bottombar.BottomBar
android:id="@+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom"
app:bb_behavior="shy|shifting"
app:bb_tabXmlResource="@xml/bottombar_tabs" />
</android.support.design.widget.CoordinatorLayout>
toolbar的布局懒得贴了,BaseActivity相信大家都有,里面有个ActivityManager,保存Activity的List。
总结一下,不管使用那种结构来显示fragment,其本质都是使用fragmentmanager管理fragment,只是有些现成的工具,比如TabHost、FragmentPagerAdapter内部使用fragmentmanager帮你管理了,使生命周期方法与Activity的同步,如果要自己写,也无可厚非。君子性非异也,善假于物也。