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

Android 实现锚点定位

Android tabLayout+recyclerView实现锚点定位

仔细看的话,这种滑动定位的功能,还可以整体滑动,再加上顶部tablayout 吸附悬停的效果。

实现效果:

布局

这里采用的是两个 tablayout。

一个用于占位,位于原始位置,scrollview内部,随scrollview滚动;另一个则是在滑动过程中,不断滑动,滑动到顶部时吸附在屏幕顶部,用户实际操作的也是这个tablayout。

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:id="@+id/scrollView"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:layout_width="match_parent"

android:layout_height="match_parent">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical">

android:layout_width="match_parent"

android:layout_height="200dp"

android:background="#ccc"

android:gravity="center">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="这里是顶部内容区域"

android:textSize="16sp" />

android:id="@+id/tablayout_holder"

android:layout_width="match_parent"

android:layout_height="50dp"

android:background="#ffffff"

app:tabIndicatorColor="@color/colorPrimary"

app:tabMode="scrollable"

app:tabSelectedTextColor="@color/colorPrimary" />

android:id="@+id/container"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

android:padding="16dp" />

android:id="@+id/tablayout_real"

android:layout_width="match_parent"

android:layout_height="50dp"

android:background="#ffffff"

android:visibility="invisible"

app:tabIndicatorColor="@color/colorPrimary"

app:tabMode="scrollable"

app:tabSelectedTextColor="@color/colorPrimary" />

实现

滑动定位的功能可以参考之前的文章,这里主要是进行吸附悬停的效果。

数据初始化:

/**

* 占位tablayout,用于滑动过程中去确定实际的tablayout的位置

*/

private TabLayout holderTabLayout;

/**

* 实际操作的tablayout,

*/

private TabLayout realTabLayout;

private CustomScrollView scrollView;

private LinearLayout container;

private String[] tabTxt = {"客厅", "卧室", "餐厅", "书房", "阳台", "儿童房"};

private List anchorList = new ArrayList<>();

//判读是否是scrollview主动引起的滑动,true-是,false-否,由tablayout引起的

private boolean isScroll;

//记录上一次位置,防止在同一内容块里滑动 重复定位到tablayout

private int lastPos = 0;

//监听判断最后一个模块的高度,不满一屏时让最后一个模块撑满屏幕

private ViewTreeObserver.OnGlobalLayoutListener listener;

for (int i = 0; i < tabTxt.length; i++) {

AnchorView anchorView = new AnchorView(this);

anchorView.setAnchorTxt(tabTxt[i]);

anchorView.setContentTxt(tabTxt[i]);

anchorList.add(anchorView);

container.addView(anchorView);

}

for (int i = 0; i < tabTxt.length; i++) {

holderTabLayout.addTab(holderTabLayout.newTab().setText(tabTxt[i]));

realTabLayout.addTab(realTabLayout.newTab().setText(tabTxt[i]));

}

一开始让实际的tablayout 移动到占位的tablayout 处,覆盖占位的tablayout。

listener = new ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

//计算让最后一个view高度撑满屏幕

int screenH = getScreenHeight();

int statusBarH = getStatusBarHeight(AliHomeMoreActivity.this);

int tabH = holderTabLayout.getHeight();

int lastH = screenH - statusBarH - tabH - 16 * 3;

AnchorView anchorView = anchorList.get(anchorList.size() - 1);

if (anchorView.getHeight() < lastH) {

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

params.height = lastH;

anchorView.setLayoutParams(params);

}

//一开始让实际的tablayout 移动到 占位的tablayout处,覆盖占位的tablayout

realTabLayout.setTranslationY(holderTabLayout.getTop());

realTabLayout.setVisibility(View.VISIBLE);

container.getViewTreeObserver().removeOnGlobalLayoutListener(listener);

}

};

container.getViewTreeObserver().addOnGlobalLayoutListener(listener);

private int getScreenHeight() {

return getResources().getDisplayMetrics().heightPixels;

}

public int getStatusBarHeight(Context context) {

int result = 0;

int resourceId = context.getResources()

.getIdentifier("status_bar_height", "dimen", "android");

if (resourceId > 0) {

result = context.getResources().getDimensionPixelSize(resourceId);

}

return result;

}

scrollview滑动

主要在滑动过程这不断监听滑动的距离,再移动实际的tablayout ,当在屏幕内时,让其一直覆盖在占位的tablayout 上,看上去是跟着scrollview 一起滑动的;当滑出屏幕时,实际的tablayout 不断移动 使其相对屏幕静止,看上去是吸附在屏幕顶部。

scrollView.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_DOWN) {

isScroll = true;

}

return false;

}

});

//监听scrollview滑动

scrollView.setCallbacks(new CustomScrollView.Callbacks() {

@Override

public void onScrollChanged(int x, int y, int oldx, int oldy) {

//根据滑动的距离y(不断变化的) 和 holderTabLayout距离父布局顶部的距离(这个距离是固定的)对比,

//当y < holderTabLayout.getTop()时,holderTabLayout 仍在屏幕内,realTabLayout不断移动holderTabLayout.getTop()距离,覆盖holderTabLayout

//当y > holderTabLayout.getTop()时,holderTabLayout 移出,realTabLayout不断移动y,相对的停留在顶部,看上去是静止的

int translation = Math.max(y, holderTabLayout.getTop());

realTabLayout.setTranslationY(translation);

if (isScroll) {

for (int i = tabTxt.length - 1; i >= 0; i--) {

//需要y减去顶部内容区域的高度(具体看项目的高度,这里demo写死的200dp)

if (y - 200 * 3 > anchorList.get(i).getTop() - 10) {

setScrollPos(i);

break;

}

}

}

}

});

private void setScrollPos(int newPos) {

if (lastPos != newPos) {

realTabLayout.setScrollPosition(newPos, 0, true);

}

lastPos = newPos;

}

tablayout点击切换

由于实际操作的是realtablayout ,所以这里只需要一直监听该tablayout。

//实际的tablayout的点击切换

realTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {

@Override

public void onTabSelected(TabLayout.Tab tab) {

isScroll = false;

int pos = tab.getPosition();

int top = anchorList.get(pos).getTop();

//同样这里滑动要加上顶部内容区域的高度(这里写死的高度)

scrollView.smoothScrollTo(0, top + 200 * 3);

}

@Override

public void onTabUnselected(TabLayout.Tab tab) {

}

@Override

public void onTabReselected(TabLayout.Tab tab) {

}

});

至此,滑动定位+顶部吸附悬停 的效果结束了。做完之后,再看这个效果,其实和 支付宝-首页 更多 那个页面里的滑动效果一样。

代码与之前文章的在同一个git地址里。

Android悬浮按钮锚点位置,Android 滑动定位+吸附悬停效果实现相关推荐

  1. android实现3种定位的切换,Android 滑动定位+吸附悬停效果实现

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

  2. android 悬浮按钮下载,简悬浮安卓版(android 悬浮按钮)V1.3.5 最新版

    简悬浮安卓版(android 悬浮按钮)是专门为广大安卓用户开发的一款悬浮按钮应用.通过简悬浮APP,用户可以开启悬浮功能设置,然后就可以自定义手势栏功能,完成一键快速操作,提高使用效率.而且还能设置 ...

  3. Android 悬浮按钮的简单实现

    Android 悬浮按钮的简单实现 package com.example.doinbackground;import android.app.Activity; import android.os. ...

  4. android 悬浮按钮和可交互提示,悬浮按钮的使用原则

    当要用悬浮的时候,考虑下在哪使用?什么条件下使用?不使用行不行?使用了带来了什么效果?如果效果不好怎么办?哪些界面需要使用?一个界面都有要展示的要素,当悬浮窗的使用是不是影响本界面的因素,其他的界面的 ...

  5. android 悬停按钮,Android悬浮按钮的使用方法

    悬浮按钮效果如下图所示: 步骤1:引用 compile 'com.laocaixw.suspendbuttonlayout:suspendbuttonlayout:1.0.3' 步骤2:xml布局 a ...

  6. android悬浮按钮阴影,浅谈FloatingActionButton(悬浮按钮)

    一.介绍 这个类是继承自ImageView的,所以对于这个控件我们可以使用ImageView的所有属性 android.support.design.widget.FloatingActionButt ...

  7. android悬浮按钮功能实现,Android中实现悬浮按钮

    在有些APP中我们需要实现一个悬浮按钮,比如图片浏览应用左右翻页功能,比如左侧悬浮功能按钮.我们要实现此功能时,最开始想到的就是用FrameLayout来实现,但是如果把按钮简单的放到FrameLay ...

  8. android 悬浮按钮 功能实现,怎么在Android中利用FloatingActionButton实现一个悬浮按钮效果...

    怎么在Android中利用FloatingActionButton实现一个悬浮按钮效果 发布时间:2020-12-02 17:41:30 来源:亿速云 阅读:238 作者:Leah 今天就跟大家聊聊有 ...

  9. android 悬浮按钮

    这里介绍一下悬浮按钮-----FloatingtActionButton的实现,以及会出现的问题. 布局文件activity_main.xml <?xml version="1.0&q ...

最新文章

  1. VML编程之------VML语言入门《VML极道教程》原著:沐缘华
  2. c++/c SM4加密解密算法代码实现
  3. [From 1.1~1.2]CLR的执行模型
  4. Oracle数据库,当DML操作时执行触发器记录日志
  5. 收藏 | 使用PyTorch时,最常见的4个错误
  6. 输出整数各位数字 (15 分)
  7. Log4J文件路径设置
  8. matlab和本机MySQL链接
  9. 但是在公司开空调睡觉还是冷
  10. 2018年机器学习算法工程师——秋招自我总结
  11. ip计算机网络适配器,如何更改计算机网络ip
  12. 医药行业gsp药店管理软件哪个好用?
  13. attiny85(digispark)零延迟启动探究
  14. 架设游戏私服——内网穿透工具frp
  15. (2)Django---用命令创建项目
  16. 打印机一页内容总是有空白
  17. 排列组合———求一串数字可以有多少种不同的组合
  18. linux proc 文件系统下 entry 的解释(转)
  19. VMware 安装出现“不能对软件降级“和“用户在命令行上发出了 EULAS_AGREED=1,表示不接受许可协议。“
  20. 数据库创建之主文件不能容纳副本的解决方案

热门文章

  1. ubuntu 修改ssh登陆端口
  2. java.lang.IllegalArgumentException: requirement failed: No output operations registered, so nothing
  3. MySQL 中 delete 语句的子查询限制
  4. leetcode 135. Candy | 135. 分发糖果(原创图文详解,Java)
  5. leetcode 303. 区域和检索 - 数组不可变(Java版)
  6. Java多线程:示例代码
  7. 响应式系统reactive system初探
  8. Spring Cloud Config入门(本地配置)
  9. kotlin学习之嵌套类和内部类(六)
  10. RSS、RSSI以及dBm相关概念