1. import android.content.Context;
  2. import android.support.design.widget.TabLayout;
  3. import android.support.v7.app.AppCompatActivity;
  4. import android.os.Bundle;
  5. import android.support.v7.widget.LinearLayoutManager;
  6. import android.support.v7.widget.RecyclerView;
  7. import android.view.MotionEvent;
  8. import android.view.View;
  9.  
  10. public class DesignStickyActivity extends AppCompatActivity {
  11. private LinearLayoutManager manager;
  12. private RecyclerView recyclerview;
  13. private String[] tabTxt = {"android", "java", "视频", "UI", "ios", "产品","老板","下午茶"};
  14. private TabLayout tabLayout;
  15. //判读是否是recyclerView主动引起的滑动,true- 是,false- 否,由tablayout引起的
  16. private boolean isRecyclerScroll;
  17. //记录上一次位置,防止在同一内容块里滑动 重复定位到tablayout
  18. private int lastPos;
  19. //用于recyclerView滑动到指定的位置
  20. private boolean canScroll;
  21. private int scrollToPosition;
  22. @Override
  23. protected void onCreate(Bundle savedInstanceState) {
  24. super.onCreate(savedInstanceState);
  25.  
  26. setContentView(R.layout.activity_design_scroll);
  27.  
  28. recyclerview = findViewById(R.id.recyclerview);
  29. tabLayout = findViewById(R.id.tablayout);
  30.  
  31. //tablayout设置标签
  32. for (int i = 0; i < tabTxt.length; i++) {
  33. tabLayout.addTab(tabLayout.newTab().setText(tabTxt[i]));
  34. }
  35. //计算内容块所在的高度,全屏高度-状态栏高度-tablayout的高度(这里固定高度50dp),用于recyclerView的最后一个item view填充高度
  36. int screenH = getScreenHeight();
  37. int statusBarH = getStatusBarHeight(this);
  38. int tabH = 50 * 3;
  39. int lastH = screenH - statusBarH - tabH;
  40. manager = new LinearLayoutManager(this);
  41. recyclerview.setLayoutManager(manager);
  42. recyclerview.setAdapter(new MyAdapter(this, tabTxt, lastH));
  43.  
  44. tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
  45. @Override
  46. public void onTabSelected(TabLayout.Tab tab) {
  47. //点击标签,使recyclerView滑动,isRecyclerScroll置false
  48. int pos = tab.getPosition();
  49. isRecyclerScroll = false;
  50. moveToPosition(manager, recyclerview, pos);
  51. }
  52.  
  53. @Override
  54. public void onTabUnselected(TabLayout.Tab tab) {
  55.  
  56. }
  57.  
  58. @Override
  59. public void onTabReselected(TabLayout.Tab tab) {
  60.  
  61. }
  62. });
  63.  
  64. recyclerview.setOnTouchListener(new View.OnTouchListener() {
  65. @Override
  66. public boolean onTouch(View v, MotionEvent event) {
  67. //当滑动由recyclerView触发时,isRecyclerScroll 置true
  68. if (event.getAction() == MotionEvent.ACTION_DOWN) {
  69. isRecyclerScroll = true;
  70. }
  71. return false;
  72. }
  73. });
  74.  
  75. recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
  76. @Override
  77. public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
  78. super.onScrollStateChanged(recyclerView, newState);
  79. if (canScroll) {
  80. canScroll = false;
  81. moveToPosition(manager, recyclerView, scrollToPosition);
  82. }
  83. }
  84.  
  85. @Override
  86. public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
  87. super.onScrolled(recyclerView, dx, dy);
  88. if (isRecyclerScroll) {
  89. //第一个可见的view的位置,即tablayou需定位的位置
  90. int position = manager.findFirstVisibleItemPosition();
  91. if (lastPos != position) {
  92. tabLayout.setScrollPosition(position, 0, true);
  93. }
  94. lastPos = position;
  95. }
  96. }
  97. });
  98.  
  99. }
  100. public void moveToPosition(LinearLayoutManager manager, RecyclerView mRecyclerView, int position) {
  101. // 第一个可见的view的位置
  102. int firstItem = manager.findFirstVisibleItemPosition();
  103. // 最后一个可见的view的位置
  104. int lastItem = manager.findLastVisibleItemPosition();
  105. if (position <= firstItem) {
  106. // 如果跳转位置firstItem 之前(滑出屏幕的情况),就smoothScrollToPosition可以直接跳转,
  107. mRecyclerView.smoothScrollToPosition(position);
  108. } else if (position <= lastItem) {
  109. // 跳转位置在firstItem 之后,lastItem 之间(显示在当前屏幕),smoothScrollBy来滑动到指定位置
  110. int top = mRecyclerView.getChildAt(position - firstItem).getTop();
  111. mRecyclerView.smoothScrollBy(0, top);
  112. } else {
  113. // 如果要跳转的位置在lastItem 之后,则先调用smoothScrollToPosition将要跳转的位置滚动到可见位置
  114. // 再通过onScrollStateChanged控制再次调用当前moveToPosition方法,执行上一个判断中的方法
  115. mRecyclerView.smoothScrollToPosition(position);
  116. scrollToPosition = position;
  117. canScroll = true;
  118. }
  119. }
  120.  
  121. private int getScreenHeight() {
  122. return getResources().getDisplayMetrics().heightPixels;
  123. }
  124.  
  125. public int getStatusBarHeight(Context context) {
  126. int result = 0;
  127. int resourceId = context.getResources()
  128. .getIdentifier("status_bar_height", "dimen", "android");
  129. if (resourceId > 0) {
  130. result = context.getResources().getDimensionPixelSize(resourceId);
  131. }
  132. return result;
  133. }
  134. }

布局:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.design.widget.CoordinatorLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. android:layout_width="match_parent"
  6.  
  7. android:layout_height="match_parent">
  8.  
  9. <android.support.design.widget.AppBarLayout
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content"
  12. android:background="@color/gray"
  13. app:elevation="0dp">
  14.  
  15. <TextView
  16. android:layout_width="match_parent"
  17. android:layout_height="200dp"
  18. android:background="@android:color/holo_orange_light"
  19. android:gravity="center"
  20. android:text="这是头部滚动部分"
  21. app:layout_scrollFlags="scroll"/>
  22.  
  23. <android.support.design.widget.TabLayout
  24. android:id="@+id/tablayout"
  25. android:layout_width="match_parent"
  26. android:layout_height="wrap_content"
  27. app:tabIndicatorColor="@color/colorAccent"
  28. app:tabMode="scrollable"
  29. app:tabSelectedTextColor="@color/colorAccent" />
  30.  
  31. </android.support.design.widget.AppBarLayout>
  32.  
  33. <android.support.v7.widget.RecyclerView
  34. android:id="@+id/recyclerview"
  35. android:layout_width="match_parent"
  36. android:layout_height="wrap_content"
  37. app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
  38.  
  39. </android.support.design.widget.CoordinatorLayout>

RecyclerView中的adapter

  1. package com.tabscroll;
  2.  
  3. import android.content.Context;
  4. import android.support.v7.widget.RecyclerView;
  5. import android.view.LayoutInflater;
  6. import android.view.View;
  7. import android.view.ViewGroup;
  8. import android.widget.LinearLayout;
  9.  
  10. public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
  11.  
  12. private Context context;
  13. private String[] tabTxt;
  14. private int lastH;
  15.  
  16. public MyAdapter(Context context, String[] tabTxt, int lastH) {
  17. this.context = context;
  18. this.tabTxt = tabTxt;
  19. this.lastH = lastH;
  20. }
  21.  
  22. @Override
  23. public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  24. View view = LayoutInflater.from(context).inflate(R.layout.adapter_view, parent, false);
  25. MyViewHolder viewHolder = new MyViewHolder(view);
  26. return viewHolder;
  27. }
  28.  
  29. @Override
  30. public void onBindViewHolder(MyViewHolder holder, int position) {
  31. holder.anchorView.setContentTxt(tabTxt[position]);
  32. holder.anchorView.setAnchorTxt(tabTxt[position]);
  33. //判断最后一个view
  34. if (position == tabTxt.length - 1) {
  35. System.out.println("positon 》"+position);
  36. if (holder.anchorView.getHeight() < lastH) {
  37. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
  38. params.height = lastH;
  39. holder.anchorView.setLayoutParams(params);
  40. }
  41. }else {
  42. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
  43. holder.anchorView.setLayoutParams(params);
  44.  
  45. }
  46. }
  47.  
  48. @Override
  49. public int getItemCount() {
  50. return tabTxt.length;
  51. }
  52.  
  53. public static class MyViewHolder extends RecyclerView.ViewHolder {
  54. private AnchorView anchorView;
  55.  
  56. public MyViewHolder(View itemView) {
  57. super(itemView);
  58. anchorView = itemView.findViewById(R.id.anchorView);
  59. }
  60. }
  61.  
  62. }

效果如下:

Android简单实现滚动悬停效果的更多相关文章

  1. Android 滑动定位+吸附悬停效果实现

    在前两篇文章中,分别介绍了tablayout+scrollview 和 tablayout+recyclerview 实现的滑动定位的功能,文章链接: Android 实现锚点定位 Android t ...

  2. JQuery实现资讯上下滚动悬停效果

    第一步:使用repeater绑定一个table. <table width="530" id="rollBar"> <asp:Repeater ...

  3. 滚动视差效果——background-attachment

    滚动视差效果的实现原理是在同一个页面上将页面元素分为多层,例如可以分为背景.内容.贴图层,在滚动页面的时候让三者滚动的速度不一,从而在人的视觉上能够形成一种立体的近似效果.最近在做一个项目wiki的时 ...

  4. Android ScrollView滚动实现大众点评、网易云音乐评论悬停效果

    今天听着网易云音乐,写着代码,真是爽翻了. http://blog.csdn.net/linshijun33/article/details/47910833 网易云音乐这个产品亮点应该在评论这一模块 ...

  5. Android对ScrollView滚动监听,实现美团、大众点评的购买悬浮效果

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17761431),请尊重他人的辛勤劳动成果,谢谢! 我之前写 ...

  6. android - TextView单行显示...或者文字左右滚动(走马灯效果)

    条件 TextView单行显示,文字左右滚动(走马灯效果)实现条件: 实现单行设置固定宽度或者设置权重都行 代码 TextView滚动必须写下面几个属性 android:singleLine=&quo ...

  7. 实例源码--Android图片滚动切换效果

    下载源码 技术要点:  1.图片滚动切换技术 2.详细的源码注释 ...... 详细介绍: 1.图片滚动切换技术 本套源码实现了类似于网站图片滚动推广效果,效果不错,很不错的参考源码 2.源码目录 运 ...

  8. 在android中用跑马灯的效果显示textview

    大家好,在我们通常的android project中,通常需要用到textview这一个布局文件,并且对于这一个显示布局所需要的文本文字内容. 下面我们就来介绍一种方法来实现在android中用跑马灯 ...

  9. Android 实现书籍翻页效果----升级篇

    自从之前发布了<Android 实现书籍翻页效果----完结篇 >之后,收到了很多朋友给我留言,前段时间由于事情较多,博客写得太匆忙很多细节地方没有描述清楚.所以不少人对其中的地方有不少不 ...

随机推荐

  1. yum nginx最新版安装

    去官方站点获取yum仓库 [root@web01 ~]# cat /etc/yum.repos.d/nginx.repo [nginx] name=nginx repo baseurl=http:// ...

  2. WIN10试用

    技巧 Win10技巧3.智能化窗口排列 排列窗口时后面的内容被挡住无疑让人倍感郁闷,Win10很好地解决了这个问题.当我们通过拖拽法将一个窗口分屏显示时(目前仅限1/2比例),操作系统就会利用屏幕剩余 ...

  3. httpd基于域名不同的虚拟主机配置

    apache2.2.x版本 1. 注释主配置文件/etc/httpd/conf/httpd.conf中的 DoucumentRoot #DocumentRoot "/var/www/html ...

  4. 基于LPCXpresso54608开发板创建Embedded Wizard UI应用程序

    平台集成和构建开发环境:LPCXpresso 54608入门指南 本文主要介绍了创建一个适用于LPCXpresso54608开发板的Embedded Wizard UI应用程序所需的所有必要步骤.请一 ...

  5. STM32 LoRaWAN探索板B-L072Z-LRWAN1中文用户手册

    UM2115用户手册 支持LoRaWAN和 LPWAN协议的STM32L0探索套件 前言 B-L072Z-LRWAN1探索套件采用了 Murata公司的CMWX1ZZABZ-091 LoRa模块.该探 ...

  6. orm多表查询基于双下划线

    ###########基于双下划线的跨表查询(基于join实现的)############# key: 正向查询按字段,反向查询按表名小写 1.查询python这本书出版社的名字 ret = Book ...

  7. .NET Core WebAPI IIS 部署问题

    虽然建了 .NET Core 的项目,基本的一些功能也实现了,运行什么的也没有问题,但是一直没有直接发布. 今天就进行了发布测试,结果问题还是来了,只是你不去做自然就不会出现. 一.基本发布 1.先是 ...

  8. PWA相关代码

    sw.js 文件 let CacheName = 'plus-v1'; var filesToCache = [ ]; self.addEventListener('install', functio ...

  9. MySQL Navicat Premium 保存sql语句

    一.新建查询 二.编写sql语句并保存 1.保存到内部 1.Ctrl+s保存当前查询文件 2.下次打开可点击查询点击上次保存的查询文件名打开上次查询的文件 2.保存到外部 1.默认保存至 C:\Use ...

  10. python中的lambda()函数

    语句:print map(lambda x:x ** 2,[1,2,3,4,5]) 其中lambda()函数在Python文档,文档中解释如下: lambda An anonymous inline ...