这是【从零撸美团】系列文章第三篇
【从零撸美团】是一个高仿美团的开源项目,旨在巩固 Android 相关知识的同时,帮助到有需要的小伙伴。
GitHub 源码地址:https://github.com/cachecats/LikeMeiTuan
每个项目基本都会有多个 Tab ,以期在有限的屏幕空间展现更多的功能。
有需求就会有市场,如今也出现了很多优秀的 tab 切换框架,使用者众多。但是深入思考之后还是决定自己造轮子~
因为框架虽好,可不要贪杯哦~
使用第三方框架最大的问题在于并不能完全满足实际需求,有的是 icon 图片 跟文字间距无法调整,有的后期会出现各种各样问题,不利于维护。
最重要的是自己写一个也不是很复杂,有研究框架填坑的时间也就写出来了。
先看怎么用:一句代码搞定
tabWidget.init(getSupportFragmentManager(), fragmentList);
再上效果图:
你没看错,长得跟美团一模一样,毕竟这个项目就叫【从零撸美团】 ㄟ( ▔, ▔ )ㄏ
一、思路
底部 tab 布局有很多实现方式,比如 RadioButton、FragmentTabHost、自定义组合View等。这里采用的是自定义组合View方式,因为可定制度更高。
滑动切换基本都是采用 ViewPager + Fragment ,集成简单,方案较成熟。这里同样采用这种方式。
二、准备
开始之前需要准备两样东西:
- 五个 tab 的选中和未选中状态的 icon 图片共计10张
- 五个 Fragment
这是最基本的素材,有了素材之后就开始干活吧~
由于要实现点击选中图片和文字都变色成选中状态,没有选中就变成灰色,所以要对每组 icon 建立一个 selector
xml文件实现状态切换。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_vector_home_pressed" android:state_activated="true" />
<item android:drawable="@drawable/ic_vector_home_normal" android:state_activated="false" />
</selector>
这里用了 android:state_activated
作为状态标记,因为最常用的 pressed
和 focused
都达不到长久保持状态的要求,都是松开手指之后就恢复了。在代码中手动设置 activated
值就好。
注意:
此处设置的是 icon 图片,所以用 android:drawable
,与下面文字使用的 android:color
有区别。
设置完图片资源后,该设置文字颜色的 selector
了,因为文字的颜色也要跟着变。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/meituanGreen" android:state_activated="true" />
<item android:color="@color/gray666" android:state_activated="false" />
</selector>
注意图片用 android:drawable
,文字用 android:color
。
三、实现
准备工作做完之后,就开始正式的自定义View啦。
1. 写布局
首先是布局文件:
widget_custom_bottom_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.v4.view.ViewPager
android:id="@+id/vp_tab_widget"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<!--下面的tab标签布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="3dp"
android:paddingTop="3dp"
>
<LinearLayout
android:id="@+id/ll_menu_home_page"
android:layout_widt