Android tabLayout+recyclerView实现锚点定位
在上一篇文章 Android 实现锚点定位中,我们介绍了tablayout+scrollView实现的锚点定位,今天我们使用tablayout+recyclerView 来实现同样的效果。
效果图:
实现思路
实现的思路与上一篇文章是一致的:
1、监听recyclerView滑动到的位置,tablayout切换到对应标签
2、tablayout各标签点击,recyclerView可滑动到对应区域
数据模拟
数据模拟,使用上一文章的AnchorView作为recyclerView的每个字view,同时这里对recyclerView的最后一个子view的高度进行修改,让其充满屏幕。
private LinearLayoutManager manager;
private String[] tabTxt = {"客厅", "卧室", "餐厅", "书房", "阳台", "儿童房"};
//判读是否是recyclerView主动引起的滑动,true- 是,false- 否,由tablayout引起的
private boolean isRecyclerScroll;
//记录上一次位置,防止在同一内容块里滑动 重复定位到tablayout
private int lastPos;
//用于recyclerView滑动到指定的位置
private boolean canScroll;
private int scrollToPosition;
//tablayout设置标签
for (int i = 0; i < tabTxt.length; i++) {
tabLayout.addTab(tabLayout.newTab().setText(tabTxt[i]));
}
//计算内容块所在的高度,全屏高度-状态栏高度-tablayout的高度(这里固定高度50dp),用于recyclerView的最后一个item view填充高度
int screenH = getScreenHeight();
int statusBarH = getStatusBarHeight(this);
int tabH = 50 * 3;
int lastH = screenH - statusBarH - tabH;
manager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
recyclerView.setAdapter(new MyAdapter(this, tabTxt, lastH));
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.anchorView.setContentTxt(tabTxt[position]);
holder.anchorView.setAnchorTxt(tabTxt[position]);
//判断最后一个view
if (position == tabTxt.length - 1) {
if (holder.anchorView.getHeight() < lastH) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.height = lastH;
holder.anchorView.setLayoutParams(params);
}
}
}
recyclerView滑动定位
当recyclerView滑动引起的,addOnScrollListener的onScrolled的监听第一个可见view的位置,直接将tablayout定位到相应的位置。
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//当滑动由recyclerView触发时,isRecyclerScroll 置true
if (event.getAction() == MotionEvent.ACTION_DOWN) {
isRecyclerScroll = true;
}
return false;
}
});
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (isRecyclerScroll) {
//第一个可见的view的位置,即tablayou需定位的位置
int position = manager.findFirstVisibleItemPosition();
if (lastPos != position) {
tabLayout.setScrollPosition(position, 0, true);
}
lastPos = position;
}
}
});
tablayout切换定位
点击tablayout进行切换,recyclerView需要滑动到相应的位置,注意这里需要根据跳转位置不同,进行相应的滑动。
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//点击标签,使recyclerView滑动,isRecyclerScroll置false
int pos = tab.getPosition();
isRecyclerScroll = false;
moveToPosition(manager, recyclerView, pos);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
public void moveToPosition(LinearLayoutManager manager, RecyclerView mRecyclerView, int position) {
// 第一个可见的view的位置
int firstItem = manager.findFirstVisibleItemPosition();
// 最后一个可见的view的位置
int lastItem = manager.findLastVisibleItemPosition();
if (position <= firstItem) {
// 如果跳转位置firstItem 之前(滑出屏幕的情况),就smoothScrollToPosition可以直接跳转,
mRecyclerView.smoothScrollToPosition(position);
} else if (position <= lastItem) {
// 跳转位置在firstItem 之后,lastItem 之间(显示在当前屏幕),smoothScrollBy来滑动到指定位置
int top = mRecyclerView.getChildAt(position - firstItem).getTop();
mRecyclerView.smoothScrollBy(0, top);
} else {
// 如果要跳转的位置在lastItem 之后,则先调用smoothScrollToPosition将要跳转的位置滚动到可见位置
// 再通过onScrollStateChanged控制再次调用当前moveToPosition方法,执行上一个判断中的方法
mRecyclerView.smoothScrollToPosition(position);
scrollToPosition = position;
canScroll = true;
}
}
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (canScroll) {
canScroll = false;
moveToPosition(manager, recyclerView, scrollToPosition);
}
}
});
至此,两种实现锚点定位的方法就介绍到这里,希望能帮助到读者在实际项目中的使用。
代码与上一篇文章的在同一个git地址里。
详细代码见
github地址:https://github.com/taixiang/tabScroll
欢迎关注我的博客:https://blog.manjiexiang.cn/
更多精彩欢迎关注微信号:春风十里不如认识你

有个「佛系码农圈」,欢迎大家加入畅聊,开心就好!
过期了,可加我微信 tx467220125 拉你入群。
Android tabLayout+recyclerView实现锚点定位的更多相关文章
- Android 实现锚点定位
相信做前端的都做过页面锚点定位的功能,通过<a href="#head"> 去设置页面内锚点定位跳转. 本篇文章就使用tablayout.scrollview来实现an ...
- [Android]使用RecyclerView替代ListView(三)
以下内容为原创,转载请注明: 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4268097.html 这次来使用RecyclerView实现Pinn ...
- [Android]使用RecyclerView替代ListView(二)
以下内容为原创,转载请注明: 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4242541.html 以前写过一篇“[Android]使用Adapte ...
- [Android]使用RecyclerView替代ListView(一)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4232560.html RecyclerView是一个比List ...
- html中设置锚点定位的几种常见方法(#号定位)
在html中设置锚点定位我知道的有几种方法,在此和大家分享一下: 1.使用id定位: <a href="#1F">锚点1</a> <div id=&q ...
- [Android]使用RecyclerView替代ListView(四:SeizeRecyclerView)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:<> [Android]使用RecyclerView替代ListView(四:SeizeRecyclerView) 在RecyclerV ...
- 【TRICK】解决锚点定位向下浮动Xpx问题
1. 问题描述 页面滚动后,菜单栏会固定在页头,当锚点定位时,菜单会遮盖部分定位后的内容,所以需要在锚点定位后自动向下漂移Xpx. 2. 解决办法 a. 利用空div 占位,如下: <a hre ...
- 当锚点定位遇上position: fixed
<!DOCTYPE html><html> <head> <title>当锚点定位遇上position: fixed</title> < ...
- 锚点定位,jquery定位到页面指定位置
jquery锚点定位 $('body,html').animate({scrollTop: $('#ter1').offset().top}, 500);#ter1是你要定位的id对象,500是0.5 ...
随机推荐
- tensorflow笔记4:函数:tf.assign()、tf.assign_add()、tf.identity()、tf.control_dependencies()
函数原型: tf.assign(ref, value, validate_shape=None, use_locking=None, name=None) Defined in tensorflo ...
- Spring Boot到底是怎么运行的,你知道吗?
导读 Spring Boot方式的项目开发已经逐步成为Java应用开发领域的主流框架,它不仅可以方便地创建生产级的Spring应用程序,还能轻松地通过一些注解配置与目前比较流行的微服务框架Spring ...
- 心路历程(五)-find work and find house
今天,对我半年的java自学经历做一个总结吧,因为今天刚找到了房子,而工作在前两天已经找到.面试了两家,第一家是海淀去知春路的中科软,去之前就百度了这家公司,各种黑,然后自己去了之后,说说自己真实的感 ...
- mysql 开发基础系列3 日期数据类型
日期类型 如果要用来表示年月日,通常用DATE 来表示. 如果要用来表示年月日时分秒,通常用DATETIME 表示. 如果只用来表示时分秒,通常用TIME 来表示. TIMESTAMP表示格式 :YY ...
- spring-boot-starter大力出奇迹
一.前言 上篇文章我们已经聊了SpringBoot的启动过程中的各类扩展点,那么从http://start.spring.io上我们生成的demo项目中,到目前就剩下了maven工程的pom.xm ...
- js变量提升与函数提升的详细过程
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
- Unity中控制天空盒移动的解决办法
为了使天空盒更真实,需要控制天空盒动态旋转. 网上找到的方法是: float num = RenderSettings.skybox.GetFloat("_Rotation"); ...
- [NewLife.XCode]数据层缓存(网站性能翻10倍)
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...
- Python机器学习笔记 K-近邻算法
K近邻(KNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一. 所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表.KNN算法的 ...
- Python多进程操作同一个文件,文件锁问题
最近工作当中做了一个项目,这个项目主要是操作文件的. 在操作耗时操作的时候,我们一般采用多线程或者多进程.在开发中,如果多个线程需要对文件进行读写操作,就需要用到线程锁或者是文件锁. 使用fcntl ...