主页面的布局很简洁,FrameLayout就是展示fragment内容的地方,下面的BottomNavigationView就是底部导航栏控件。
二、实现底部导航栏布局效果
public class MainActivity extends AppCompatActivity { @BindView(R.id.fr_content)
FrameLayout frContent; @BindView(R.id.bnv_item)
BottomNavigationView mBottomView; //...
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
BottomNavigationItem bottomNavigationItem=new BottomNavigationItem("首页",
ContextCompat.getColor(this,R.color.mainPager),R.drawable.loudspeaker);
BottomNavigationItem bottomNavigationItem1=new BottomNavigationItem("编程",
ContextCompat.getColor(this,R.color.programCode),R.drawable.program);
BottomNavigationItem bottomNavigationItem2=new BottomNavigationItem("读书",
ContextCompat.getColor(this,R.color.readPager),R.drawable.book);
BottomNavigationItem bottomNavigationItem3=new BottomNavigationItem("理财",
ContextCompat.getColor(this,R.color.manageMoneyPager),R.drawable.money);
mBottomView.addTab(bottomNavigationItem);
mBottomView.addTab(bottomNavigationItem1);
mBottomView.addTab(bottomNavigationItem2);
mBottomView.addTab(bottomNavigationItem3); //...
}
代码很清晰,创建底部的多个item实例,再将其加入到该view中。
这里我做了一下怪[啊哈哈],使用了ButterKnife来获取控件,你可以不用,按照最原始的方式即可。到这里已经完成了一小半了,够快吧....
三、准备一个Fragment
这里我们创建了4个fragment,分别是首页、编程、读书和理财。我就拿理财来举例了(最近迷上了理财这个东西),其他三个都是一样的,或许这就是传说中的举一反三吧。
ManageMoneyFragment.class
public class ManageMoneyFragment extends Fragment { private static final String TAG = "ManageMoneyFragment"; @Override
public void onAttach(Context context) {
Log.d(TAG, "onAttach: "); super.onAttach(context);
} @Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateView: "); return inflater.inflate(R.layout.manage_money_fragment,null);
} @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "onViewCreated: "); super.onViewCreated(view, savedInstanceState);
} @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "onActivityCreated: "); super.onActivityCreated(savedInstanceState);
} @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreate: "); super.onCreate(savedInstanceState);
} @Override
public void onStart() {
Log.d(TAG, "onStart: "); super.onStart();
} @Override
public void onResume() {
Log.d(TAG, "onResume: "); super.onResume();
} @Override
public void onPause() {
Log.d(TAG, "onPause: "); super.onPause();
} @Override
public void onStop() {
Log.d(TAG, "onStop: "); super.onStop();
} @Override
public void onDestroy() {
Log.d(TAG, "onDestroy: "); super.onDestroy();
} @Override
public void onDestroyView() {
Log.d(TAG, "onDestroyView: "); super.onDestroyView();
} @Override
public void onDetach() {
Log.d(TAG, "onDetach: "); super.onDetach();
}
}
写了这么长一串感觉啥也没做啊,就是写了几个类似activity的生命周期方法。是的,这些都是Fragment的生命周期方法,写这个目的是为了下面谈谈一些它的生命周期。
其实Fragment可以算Android里的第五大组件了,之前,有人把View作为第五大组件,但是由于相对于四大组件来说它没有生命周期,所以从这个角度来说,Fragment更适合称为第五大组件。
创建一个fragment到用户能看到的状态经历了以下的生命周期

创建fragment.png
同样销毁一个fragment会经历如下生命周期

销毁fragment.png
或许这张图看起来会更清晰明了一点

fragment生命周期.png
相比于Activity,它的生命周期方法多了几个,比如它最开始的方法走的是onAttach,销毁的最后一步是onDetach方法,它们是一对方法因为fragment是需要依附Activity存在的,所以就有了这样的两个方法。
好,可以回归正题了,在上面代码中和我们的页面view直接相关的是 onCreateView方法,用inflater.inflate方法把fragment的页面布局填充进去就好了
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.d(TAG, "onCreateView: "); return inflater.inflate(R.layout.manage_money_fragment,null);
}
随便写了一个简单的布局
R.layout.manage_money_fragment
<?xml version="1.0" encoding="utf-8"?><RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frag_manage_money"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="35sp"
android:layout_centerInParent="true"
android:text=" 在别人贪婪的时候,我们要恐惧;
在别人恐惧的时候,我们要贪婪;"/></RelativeLayout>
四、依附到Activity中
这是最后一步也是最关键的一步,fragment是需要依附到Activity中的。
在底部的导航栏view中,是有个点击方法的,通过这个点击方法我们对每个item进行选择,从而切换到相应的fragment
public class MainActivity extends AppCompatActivity { //当前的fragment
private Fragment mCurrFragment=new Fragment(); //理财的fragment
private ManageMoneyFragment mManageMoneyFragment=new ManageMoneyFragment(); //编程的fragment
private ProgramFragment mProgramFragment=new ProgramFragment(); //阅读的fragment
private ReadFragment mReadFragment=new ReadFragment(); @Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //....省略上面已展示的
//点击底部按钮选择对应的fragment
mBottomView.setOnBottomNavigationItemClickListener(new OnBottomNavigationItemClickListener() { @Override
public void onNavigationItemClick(int index) { switch (index){ case 0:
skipToHome(); break; case 1:
skipToProgram(); break; case 2:
skipToRead(); break; case 3:
skipToManage(); break; default: break;
}
}
});
} //跳转到理财fragment
private void skipToManage() {
switchFragment(mManageMoneyFragment);
}
//.....
因为在添加导航栏的item时,它的内部实现是ArrayList,所以只需要判断它的index就可以获取对应的item了。
选择完后,进行fragment的展示。这里我们使用的hide和show的方式,对于没有添加到ArrayList的,需要先添加再展示,对于已经添加过的我们直接展示就好了,注意在展示之前要将当前展示的先隐藏。
对于隐藏这样的方式就有个好处,我们不需要重复创建它的实例,节省了不必要消耗的性能和用户的流量。
private void switchFragment(Fragment targetFragment){
FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction(); //隐藏目前的fragment,展示目标fragment
if(!targetFragment.isAdded()){
fragmentTransaction.hide(mCurrFragment)
.add(R.id.fr_content,targetFragment,targetFragment.getClass().getName())
.commit();
}else {
fragmentTransaction.hide(mCurrFragment)
.show(targetFragment)
.commit();
}
mCurrFragment=targetFragment;
}
作者:树獭非懒
链接:https://www.jianshu.com/p/6ea2b8b10b62