上文提到,重构后,SuspensionDecoration
数据源依赖的接口是ISuspensionInterface
,
如下:
public interface ISuspensionInterface {
//是否需要显示悬停title
boolean isShowSuspension();
//悬停的title
String getSuspensionTag();
}
在BaseIndexBean
里实现,默认显示悬停,分组title和IndexBar的Tag是一样的。
public abstract class BaseIndexBean implements ISuspensionInterface {
private String baseIndexTag;//所属的分类(城市的汉语拼音首字母)
@Override
public String getSuspensionTag() {
return baseIndexTag;
}
@Override
public boolean isShowSuspension() {
return true;
}
}
而BaseIndexPinyinBean
类,现在如下:
public abstract class BaseIndexPinyinBean extends BaseIndexBean {
private String baseIndexPinyin;//城市的拼音
//是否需要被转化成拼音, 类似微信头部那种就不需要 美团的也不需要
//微信的头部 不需要显示索引
//美团的头部 索引自定义
//默认应该是需要的
public boolean isNeedToPinyin() {
return true;
}
//需要转化成拼音的目标字段
public abstract String getTarget();
}
所以我们需要实现微信那种效果,只需要重写isShowSuspension()
和isNeedToPinyin()
这两个方法,并setBaseIndexTag()
直接设置tag即可。
仿美团选择城市
=======
这个页面还是挺麻烦的,所以步骤也最多。建议结合代码阅读Demo及库地址。
分析美团选择城市列表:
* 主体部分仍旧是一个普通的 分组悬停&索引导航 的列表(美团没有悬停功能)。
* 头部是由若干复杂HeaderView组成。
* 从右侧索引栏可以看出,定位、最近、热门这三个Item对应了列表三个HeaderView。
* 最顶部的HeaderView是不需要分组,也不需要索引的。
那么逐一实现:
主体部分
很简单,根据前文最后的封装( 第二篇戳我),如果只有主体部分,我们需要让主体部分的JavaBean继承自BaseIndexPinyinBean
,然后正常构建数据,最终设置给IndexBar和SuspensionDecoration即可。
public class MeiTuanBean extends BaseIndexPinyinBean {
private String city;//城市名字
…
@Override
public String getTarget() {
return city;
}
}
头部若干HeaderViews
这里不管是通过HeaderView添加进来头部布局,还是通过itemViewType自己去实现,核心都是通过itemViewType去做的。
也就是说头部的HeaderView也是RecyclerView的Item。
既然是Item一定对应着相应的JavaBean。
我们需要针对这些JavaBean让其分别继承BaseIndexPinyinBean
。
具体怎么实现头部布局不是本文重点,不再赘述,Demo里有代码可细看Demo及库地址。
定、近、热三个HeaderView的处理
定、近、热三个HeaderView有如下特点:
* 右侧导航索引的title 为自定义,不是拼音首字母则也不需要排序。
* 悬停分组的title 和 右侧导航索引的title 不一样,则悬停分组的title也需要自定义。
做法:
不过既然是RecyclerView里的Item,又有 悬停分组、索引导航 特性。那么就要继承BaseIndexPinyinBean
。
* 不需要转化成拼音且不排序,则重写isNeedToPinyin()
返回false,并调用setBaseIndexTag(indexBarTag)
给右侧索引赋值。
* 需要自定义悬停分组的title,则重写getSuspensionTag()
返回title。
public class MeituanHeaderBean extends BaseIndexPinyinBean {
private List cityList;
//悬停ItemDecoration显示的Tag
private String suspensionTag;
public MeituanHeaderBean(List cityList, String suspensionTag, String indexBarTag) {
this.cityList = cityList;
this.suspensionTag = suspensionTag;
this.setBaseIndexTag(indexBarTag);
}
@Override
public String getTarget() {
return null;
}
@Override
public boolean isNeedToPinyin() {
return false;
}
@Override
public String getSuspensionTag() {
return suspensionTag;
}
}
用private List<MeituanHeaderBean> mHeaderDatas;
保存定、近、热头部数据源,最终需要将其设置给IndexBar
和SuspensionDecoration
。
mHeaderDatas = new ArrayList<>();
List locationCity = new ArrayList<>();
locationCity.add(“定位中”);
mHeaderDatas.add(new MeituanHeaderBean(locationCity, “定位城市”, “定”));
List recentCitys = new ArrayList<>();
mHeaderDatas.add(new MeituanHeaderBean(recentCitys, “最近访问城市”, “近”));
List hotCitys = new ArrayList<>();
mHeaderDatas.add(new MeituanHeaderBean(hotCitys, “热门城市”, “热”));
最顶部的HeaderView
最顶部的HeaderView,由于不需要右侧索引,也没有悬停分组。它只是一个普通的HeaderView即可。
对于这种需求的HeaderView,只需要将它们的数量传给IndexBar
和SuspensionDecoration
即可。
在内部我已经做了处理,保证联动坐标和数据源下标的正确。
mDecoration.setHeaderViewCount(mHeaderAdapter.getHeaderViewCount() - mHeaderDatas.size()));
mIndexBar.setHeaderViewCount(mHeaderAdapter.getHeaderViewCount() - mHeaderDatas.size());
这里用headerView一共的count=4,减去上步中mHeaderDatas
的size =3,得出不需要右侧索引,也没有悬停分组 头部的数量。
将主体数据集和头部数据集合并
我们前几步中,设计到了三部分数据集,
一部分是主体数据集,
//主体部分数据源(城市数据)
private List mBodyDatas;
第二部分是需要特性的头部数据集
//头部数据源
private List mHeaderDatas;
第三部分是不需要特性的数据集,这里忽略。我们只用到它的count。
我们需要将第一和第二部分融合,并且设置给IndexBar
和SuspensionDecoration
。
则我们利用它们共同的基类,BaseIndexPinyinBean
来存储。
核心代码如下:
//设置给InexBar、ItemDecoration的完整数据集
private List mSourceDatas;
mSourceDatas.addAll(mHeaderDatas);
mSourceDatas.addAll(mBodyDatas);
设置给IndexBar
:
mIndexBar.setmPressedShowTextView(mTvSideBarHint)//设置HintTextView
.setNeedRealIndex(true)//设置需要真实的索引
.setmLayoutManager(mManager)//设置RecyclerView的LayoutManager
.setHeaderViewCount(mHeaderAdapter.getHeaderViewCount() - mHeaderDatas.size());
.setmSourceDatas(mSourceDatas)//设置数据
设置给SuspensionDecoration
:
mRv.addItemDecoration(new SuspensionDecoration(this, mSourceDatas)
.setHeaderViewCount(mHeaderAdapter.getHeaderViewCount() - mHeaderDatas.size()));
效果图如文首。
核心代码
这里再提一点,我已经将排序功能抽离至IndexBar
的IIndexBarDataHelper
类型变量中去做,
在mIndexBar.setmSourceDatas(mSourceDatas)
时会自动排序。
也可以手动调用mIndexBar.getDataHelper().sortSourceDatas(mBodyDatas);
排序。
像本节的案例,可以选择先排序bodyDatas,然后再合并至sourceDatas,最终设置给IndexBar
和SuspensionDecoration
。
如:
//先排序
mIndexBar.getDataHelper().sortSourceDatas(mBodyDatas);
mSourceDatas.addAll(mBodyDatas);
mIndexBar.setmSourceDatas(mSourceDatas)//设置数据
.invalidate();
mDecoration.setmDatas(mSourceDatas);
涉及到的重构代码:
除了上节提到的那些数据结构的重构,
我还将以前在IndexBar里完成的:
-
1 将汉语转成拼音
-
2 填充indexTag
-
3 排序源数据源
-
4 根据排序后的源数据源->indexBar的数据源
抽成一个接口表示,与IndexBar分离。
/**
-
介绍:IndexBar 的 数据相关帮助类
-
1 将汉语转成拼音
-
2 填充indexTag
-
3 排序源数据源
-
4 根据排序后的源数据源->indexBar的数据源
-
作者:zhangxutong
-
邮箱:mcxtzhang@163.com
-
主页:http://blog.csdn.net/zxt0601
-
时间: 2016/11/28.
*/
public interface IIndexBarDataHelper {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
尾声
最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。
Android进阶学习资料库
一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!
-
自行下载直达领取链接:点击这里前往GitHub
人员,请集中精力,对基础和重要的事情做深度研究。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。
[外链图片转存中…(img-YRkahmS4-1710853230295)]
Android进阶学习资料库
一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!
[外链图片转存中…(img-GkooYn28-1710853230296)]
-
自行下载直达领取链接:点击这里前往GitHub