提筆犯怵,好久沒總結幹貨了,知識普遍都是碎片化的,記錄在雲筆記裡的比較多和雜。
最近項目用了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 = ;
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 = ; 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 = ;
BottomBarTab nearby = bottomBar.getTabWithId(R.id.tab_nearby);
nearby.setBadgeCount();
break;
case R.id.tab_nearby:
currIndex = ;
break;
case R.id.tab_friends:
currIndex = ;
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的同步,如果要自己寫,也無可厚非。君子性非異也,善假于物也。