原文链接:https://mp.weixin.qq.com/s/L3o2i3WTmg1ScXEYDS8YCg

在上一篇文章 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滑动引起的,addOnScrollListeneronScrolled的监听第一个可见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实现锚点定位的更多相关文章

  1. Android 实现锚点定位

    相信做前端的都做过页面锚点定位的功能,通过<a href="#head"> 去设置页面内锚点定位跳转. 本篇文章就使用tablayout.scrollview来实现an ...

  2. [Android]使用RecyclerView替代ListView(三)

    以下内容为原创,转载请注明: 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4268097.html  这次来使用RecyclerView实现Pinn ...

  3. [Android]使用RecyclerView替代ListView(二)

    以下内容为原创,转载请注明: 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4242541.html 以前写过一篇“[Android]使用Adapte ...

  4. [Android]使用RecyclerView替代ListView(一)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4232560.html RecyclerView是一个比List ...

  5. html中设置锚点定位的几种常见方法(#号定位)

    在html中设置锚点定位我知道的有几种方法,在此和大家分享一下: 1.使用id定位: <a href="#1F">锚点1</a> <div id=&q ...

  6. [Android]使用RecyclerView替代ListView(四:SeizeRecyclerView)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:<> [Android]使用RecyclerView替代ListView(四:SeizeRecyclerView) 在RecyclerV ...

  7. 【TRICK】解决锚点定位向下浮动Xpx问题

    1. 问题描述 页面滚动后,菜单栏会固定在页头,当锚点定位时,菜单会遮盖部分定位后的内容,所以需要在锚点定位后自动向下漂移Xpx. 2. 解决办法 a. 利用空div 占位,如下: <a hre ...

  8. 当锚点定位遇上position: fixed

    <!DOCTYPE html><html> <head> <title>当锚点定位遇上position: fixed</title> < ...

  9. 锚点定位,jquery定位到页面指定位置

    jquery锚点定位 $('body,html').animate({scrollTop: $('#ter1').offset().top}, 500);#ter1是你要定位的id对象,500是0.5 ...

随机推荐

  1. Excel 斜线表头制作方法

    Excel 斜线表头制作方法

  2. VueJs(1)---快速上手VueJs

    [VueJs入门] 版权声明 首先申明:此篇博客不是本人原创,只是最近开始学习vue.jS,看到有作者写的很不错,我仅在它的基础上仅仅是修改了样式 原文博客地址:https://blog.csdn.n ...

  3. redis 系列2 知识点概述

    一.概述 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表 ...

  4. 我可能不懂Array.prototype.sort

    今天 fix 我们后台系统的一些 bug.系统是基于 beego 和模板开发的,各种前后端代码揉作一团,没有格式,没有 eslint,全局变量满天飞,连 js 代码都有后端的插值,读起来非常 酸爽. ...

  5. 《HelloGitHub月刊》第 03 期

    <HelloGithub>第03期 兴趣是最好的老师,而<HelloGitHub> 就是帮你找到兴趣! 因为我比较熟悉python语言,所以月刊中python语言的项目居多,个 ...

  6. Windows 上的 SSH?使用 PowerShell Remoting 远程管理 Windows 服务器

    作者:陈计节 个人博客:https://blog.jijiechen.com/post/powershell-remoting/ 在 Linux/Unix 世界里 SSH 是个好东西,SSH 是 Se ...

  7. 【深度学习与TensorFlow 2.0】入门篇

    注:因为毕业论文需要用到相关知识,借着 TF 2.0 发布的时机,重新捡起深度学习.在此,也推荐一下优达学城与 TensorFlow 合作发布的TF 2.0入门课程,下面的例子就来自该课程. 原文发布 ...

  8. 项目详解2—LVS负载均衡详解

    一.负载均衡集群介绍 1.集群 ① 集群(cluster)技术是一种较新的技术,通过集群技术,可以在付出较低成本的情况下获得在性能.可靠性.灵活性方面的相对较高的收益,其任务调度则是集群系统中的核心技 ...

  9. 监控报I/O问题,怎么办?

    Linux系统出现了性能问题,一般我们可以通过top.iostat.free.vmstat等命令来查看初步定位问题.其中iostat可以给我们提供丰富的IO状态数据. 一.查询命令基本使用 1.命令介 ...

  10. DocumentFragment对象

    一般动态创建html元素都是创建好了直接appendChild()上去,但是如果要添加大量的元素还用这个方法的话就会导致大量的重绘以及回流,所以需要一个'缓存区'来保存创建的节点,然后再一次性添加到父 ...