Android 快速开发(二),封装一个 BottomTabBaseActivity
Android 快速开发(二),封装一个 BottomTabBaseActivity
生命不息,奋斗不止,万事起于忽微,量变引起质变。 —— 鸿洋
前言
上一篇我们详细介绍了 Android 快速开发(一),封装一个 TopBarBaseActivity 效果是显而易见的。接下来我们进行 Android 快速开发(二)。
效果
什么是快速开发嘞,看这个效果
然而实现 BottomTab + ViewPager 的效果我只用了这么几行代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class TestBottomTabBaseActivity extends BottomTabBaseActivity {
@Override
protected List<BottomTabView.TabItemView> getTabViews() {
List<BottomTabView.TabItemView> tabItemViews = new ArrayList<>();
tabItemViews.add(new BottomTabView.TabItemView(this, "标题1", R.color.colorPrimary,
R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round));
tabItemViews.add(new BottomTabView.TabItemView(this, "标题2", R.color.colorPrimary,
R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round));
tabItemViews.add(new BottomTabView.TabItemView(this, "标题3", R.color.colorPrimary,
R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round));
tabItemViews.add(new BottomTabView.TabItemView(this, "标题4", R.color.colorPrimary,
R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round));
return tabItemViews;
}
@Override
protected List<Fragment> getFragments() {
List<Fragment> fragments = new ArrayList<>();
fragments.add(new TabFragment1());
fragments.add(new TabFragment2());
fragments.add(new TabFragment3());
fragments.add(new TabFragment4());
return fragments;
}
}
|
添加 CenterView 也很简单,只需重写 getCenterView 方法并返回你想添加的 View。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Override
protected View getCenterView() {
ImageView centerView = new ImageView(this);
centerView.setImageResource(R.mipmap.ic_launcher_round);
centerView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Toast 一个 "centerView 点击了";
}
});
return centerView;
}
|
为什么会这么简单呢,因为我把重复性的代码都封装在 父类
BottomTabBaseActivity 里面,这样的话,我们想实现 BottomTab + ViewPager 的效果只需实现三个方法,这样就可以大大提高我们的效率。爽YY~~~ 接下来我们一起实现这个 BottomTabBaseActivity。
BottomTabView
首先我介绍一下我自定义一个 BottomTabView,用于实现 Tab 效果
-
它提供两个 setTabItemViews 方法,用于初始化 TabItem 的数据和 CenterView
12setTabItemViews(List<TabItemView> tabItemViews);setTabItemViews(List<TabItemView> tabItemViews, View centerView); -
提供 setOnTabItemSelectListener 方法,用于设置 TabItem 的选择监听,可以实现 ViewPager 的页面切换或者 Fragment 切换。
123456bottomTabView.setOnTabItemSelectListener(new BottomTabView.OnTabItemSelectListener() {@Overridepublic void onTabItemSelect(int position) {//viewPager.setCurrentItem(position, true);}}); -
还提供 setOnSecondSelectListener ,当 TabItemView 已经被选择并再次点击时,会出发此监听,用于实现某些 App 二次点击 TabItemView 刷新功能。
1
2
3
4
5
6
|
bottomTabView.setOnSecondSelectListener(new BottomTabView.OnSecondSelectListener() {
@Override
public void onSecondSelect(int position) {
//refresh();
}
});
|
你可以直接粘贴项目中这两个文件即可BottomTabView.java
view_tab_item.xml
GitHub 地址
开始
下面利用 BottomTabView 实现我们想要的 BottomTabBaseActivity
搭建整体布局
我们新建两个文件 BottomTabBaseActivity.java 和 activity_base_bottom_tab.xml,并把 BottomTabView.java 和 view_tab_item.xml 复制到我们的项目中
activity_base_bottom_tab.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<View
android:layout_width="match_parent"
android:background="#c7c7c7"
android:layout_height="0.1dp"/>
<cn.ifmvo.bottomtab.BottomTabView
android:id="@+id/bottomTabView"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="50dp"/>
</LinearLayout>
|
BottomTabBaseActivity 设置成抽象类,并添加三个方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public abstract class BottomTabBaseActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_bottom_tab);
}
}
protected abstract List<BottomTabView.TabItemView> getTabViews();
protected abstract List<Fragment> getFragments();
protected View getCenterView(){
return null;
}
|
我们为什么写两个 abstract 类型的方法呢,我们的思路是这样的:
- 可变的东西(底部菜单的 Item、Fragment)放在子类去实现
- 父类 BottomTabBaseActivity 实现不变的、重复性的代码
所以声明两个抽象方法 getTabViews、getFragments ,并在子类去实现,至于 getCenterView 方法可以自行定制,如果需要 CenterView 在子类实现方法即可。
MainActivity 继承自 BottomTabBaseActivity,只需实现两个方法,其他的什么也不需要做。
1
2
3
4
5
6
7
8
9
10
11
12
|
public class MainActivity extends BottomTabBaseActivity {
@Override
protected List<BottomTabView.TabItemView> getTabViews() {
return null;
}
@Override
protected List<Fragment> getFragments() {
return null;
}
}
|
到这里,整体的布局已经搭建完毕,下面我们来实现功能.
实现底部 Tab
在 BottomTabBaseActivity 中添加:
1
2
3
4
5
|
if (getCenterView() == null){
bottomTabView.setTabItemViews(getTabViews());
}else {
bottomTabView.setTabItemViews(getTabViews(), getCenterView());
}
|
在 MainActivity 中实现 getTabView 方法
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Override
protected List<BottomTabView.TabItemView> getTabViews() {
List<BottomTabView.TabItemView> tabItemViews = new ArrayList<>();
tabItemViews.add(new BottomTabView.TabItemView(this, "标题1", R.color.colorPrimary,
R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round));
tabItemViews.add(new BottomTabView.TabItemView(this, "标题2", R.color.colorPrimary,
R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round));
tabItemViews.add(new BottomTabView.TabItemView(this, "标题3", R.color.colorPrimary,
R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round));
tabItemViews.add(new BottomTabView.TabItemView(this, "标题4", R.color.colorPrimary,
R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round));
return tabItemViews;
}
|
TabItemView 构造方法的参数含义
1
2
3
4
5
6
7
8
|
/**
* @param title 标题
* @param colorDef 标题默认的颜色
* @param colorPress 标题被选中时的颜色
* @param iconResDef 默认的图标
* @param iconResPress 被选中时的图标
*/
public TabItemView(Context context, String title, int colorDef, int colorPress, int iconResDef, int iconResPress);
|
现在你可以运行一下你的 MainActivity,是不是已经实现了 底部 Tab 的效果。
连接 BottomTabView 和 ViewPager
我们继续。接下来我们将 BottomTabView 和 ViewPager 进行连接,并切换 ViewPager 的页面,以显示不同的 Fragment。
声明、初始化一个 Adapter,并设置到 ViewPager 里面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
FragmentPagerAdapter adapter;
adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return getFragments().get(position);
}
@Override
public int getCount() {
return getFragments().size();
}
};
viewPager.setAdapter(adapter);
|
利用 setOnTabItemSelectListener 方法设置 BottomTabView 的监听器,来切换 ViewPager
1
2
3
4
5
6
|
bottomTabView.setOnTabItemSelectListener(new BottomTabView.OnTabItemSelectListener() {
@Override
public void onTabItemSelect(int position) {
viewPager.setCurrentItem(position, true);
}
});
|
用 ViewPager 的 addOnPageChangeListener 方法,使 ViewPager 切换的时候,也同步切换 BottomTabView 的选中位置。
1
2
3
4
5
6
7
8
9
10
11
12
|
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
@Override
public void onPageSelected(int position) {
bottomTabView.updatePosition(position);
}
@Override
public void onPageScrollStateChanged(int state) {}
});
|
最后一步:实现 getFragments 方法 返回一个 List
1
2
3
4
5
6
7
8
9
|
@Override
protected List<Fragment> getFragments() {
List<Fragment> fragments = new ArrayList<>();
fragments.add(new TabFragment1());
fragments.add(new TabFragment2());
fragments.add(new TabFragment3());
fragments.add(new TabFragment4());
return fragments;
}
|
当然 TabFragment 需要你自己去实现。 现在你再运行一下你的 MainActivity,是不是已经实现了。
你想一想,以后每个 BottomTab + ViewPager 的界面,只需 让你的 XXActivity extends BottomTabBaseActivity,再实现两个方法就可以了,多爽啊!
添加 CenterView
如果你想添加一个 CenterView 的话,你可以实现 getCenterView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@Override
protected View getCenterView() {
ImageView centerView = new ImageView(this);
centerView.setImageResource(R.mipmap.ic_launcher_round);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, 200);
layoutParams.leftMargin = 60;
layoutParams.rightMargin = 60;
layoutParams.bottomMargin = 0;
centerView.setLayoutParams(layoutParams);
centerView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
return centerView;
}
|
或者这样写比较灵活:
1
2
3
4
5
6
7
8
9
10
11
|
@Override
protected View getCenterView() {
View centerView = LayoutInflater.from(this).inflate(R.layout.centerview, null);
centerView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
return centerView;
}
|
如果你想让 CenterView 的上边界暴露在 BottomTabView 的外面的话,只需修改两处代码:
- 将 BottomTabView 内部的 View 设置成 底部对齐
- 在最外层布局添加属性并设置成 false
前提是你要保证 BottomTabView 内部的 CenterView 足够大。
activity_base_bottom_tab.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
...
android:clipChildren="false"
...>
...
<cn.ifmvo.bottomtab.BottomTabView
...
android:gravity="bottom"
.../>
</LinearLayout>
|
Prefect !~~
GitHub 地址
本文出自 陈序员 的博客,转载必须注明出处。
https://blog.ifmvo.cn/2017/05/03/package-bottomtabbaseactivity/
陈序员