一、 概述
当我们开发 Android 应用时,经常会有制作底部导航的需求。
做这类导航的方式很多,我们可以在底部做一个横向的 RadioGroup,在其中放几个 RadioButton,每次点击不同的 RadioButton 时就切换不同的 Fragment。或者可以使用 ViewPager 来存放 Fragment,在滑动的时候切换不同的界面。
但是这种导航在美观上始终有一点欠缺,而 PagerBottomTabStrip 框架不仅可以帮你调整布局,还可以设置炫酷的动画效果,对开发者来不能更完美。
大概效果如下,当选中一个页面时,底部对应的导航图标和文字会放大,而且这种放大还有动画效果。
底部导航.gif
二、代码
1. 布局
整个布局为相对布局,底部是框架中的控件,中间是一个 ViewPager。
<?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"
android:orientation="vertical"
tools:context="com.learn.lister.frames.MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/main_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
<me.majiajie.pagerbottomtabstrip.PagerBottomTabLayout
android:id="@+id/main_tab"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:layout_height="80dp"/>
</RelativeLayout>
2. MainActivity
在写 MainActivity 之前,我们需要先写四个填充到 ViewPager 中的 Activity。
我们会将这四个 Activity 的 View 添加到 List< View > 中,你可能会觉得 LocalActivityManager 一下子运行了多个 Activity,其实并没有。它实际上仅仅运行了其中一个,那些嵌入的 Activity 仅仅是贡献了自己所包含的 Window 窗口而已。
public class MainActivity extends AppCompatActivity {
public static final int PAGE_HOME = 0;
public static final int PAGE_NEARBY = 1;
public static final int PAGE_SEARCH = 2;
public static final int PAGE_MINE = 3;
private PagerBottomTabLayout mTabLayout;
private ViewPager mViewPager;
private Controller mController;
/**
* 在这个案例中,我们需要往 ViewPager 中添加 Activity,但是 ViewPager 加载的是 View 对象
* 所以在这里我们需要把 Activity 转化为 View 对象,因此需要 LocalActivityManager 类
* LocalActivityManager 类是管理 Activity 的,然后通过 startActivity() 这个方法获取当前 Window 对象
* 再调用 getDecorView() 方法获取当前 Activity 对应的 View
*/
private LocalActivityManager mManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mManager = new LocalActivityManager(this, true);
mManager.dispatchCreate(savedInstanceState);
mTabLayout = (PagerBottomTabLayout) findViewById(R.id.main_tab);
mViewPager = (ViewPager) findViewById(R.id.main_pager);
mTabLayout.setBackgroundColor(Color.argb(100, 246, 246, 246));
mController = mTabLayout.builder()
.addTabItem(R.drawable.home_normal, "首页", getResources().getColor(R.color.colorPrimary))
.addTabItem(R.drawable.nearby_normal, "附近", getResources().getColor(R.color.colorPrimary))
.addTabItem(R.drawable.search_normal, "搜索", getResources().getColor(R.color.colorPrimary))
.addTabItem(R.drawable.account_normal, "我的", getResources().getColor(R.color.colorPrimary))
.build();
setListener();
addActivities();
mViewPager.setCurrentItem(0);
}
private void setListener() {
mController.addTabItemClickListener(new OnTabItemSelectListener() {
@Override
public void onSelected(int index, Object tag) {
switch (index) {
case PAGE_HOME:
mViewPager.setCurrentItem(PAGE_HOME);
mController.setSelect(PAGE_HOME);
break;
case PAGE_NEARBY:
mViewPager.setCurrentItem(PAGE_NEARBY);
mController.setSelect(PAGE_NEARBY);
break;
case PAGE_SEARCH:
mViewPager.setCurrentItem(PAGE_SEARCH);
mController.setSelect(PAGE_SEARCH);
break;
case PAGE_MINE:
mViewPager.setCurrentItem(PAGE_MINE);
mController.setSelect(PAGE_MINE);
break;
}
}
@Override
public void onRepeatClick(int index, Object tag) {
}
});
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mController.setSelect(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void addActivities() {
List<View> views = new ArrayList<>();
Intent intent = new Intent();
intent.setClass(this, HomeActivity.class);
views.add(getView("activity_home", intent));
intent.setClass(this, NearbyActivity.class);
views.add(getView("activity_nearby", intent));
intent.setClass(this, SearchActivity.class);
views.add(getView("activity_search", intent));
intent.setClass(this, AccountActivity.class);
views.add(getView("activity_account", intent));
mViewPager.setAdapter(new MyViewPagerAdapter(views));
}
/**
* LocalActivityManager 提供了一个重要方法 startActivity()
* 该方法正是利用主线程 mActivityThread 去装载指定的 Activity
*/
private View getView(String id, Intent intent) {
return mManager.startActivity(id, intent).getDecorView();
}
}
3. 适配器 MyViewPagerAdapter
public class MyViewPagerAdapter extends PagerAdapter implements Serializable {
private List<View> views;
public MyViewPagerAdapter(List<View> views) {
this.views = views;
}
@Override
public int getCount() {
return views.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(views.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(views.get(position), 0);
return views.get(position);
}
}
三、总结
如果你运行了这个案例,你会发现 LocalActivityManager 已经过时了,因为在 ViewPager 中添加 Activity 的确很麻烦,我认为谷歌应该是建议我们使用 Fragment,相比 Activity,Fragment 更小巧也更灵活,感兴趣的话就试一下吧。
网友评论