Android实现网易严选标签栏滑动效果

标签栏是一个非常常见的控件,似乎也是一个比较简单的控件,但如果在标签下方加个下划线的话,就还是可以玩出挺多花来的。

网易严选的标签栏就做的很不错,里面隐藏着诸多细节:

手动滑动页面,下划线会跟着滑动。 选择一个标签后,下划线会有滑动过去的动画。 选择最左端或最右端的标签,标签栏会进行滑动,使得标签向中间靠拢(如果可以滑的话)。

仔细分析下,需要在简单标签栏的基础上实现以下逻辑:

画出下划线。 监听手动滑动页面事件,实时更新下划线位置。 切换标签时,开始下划线滑动的动画,并判断是否要同时滑动标签栏。

我做了一个样例程序,其中的较难点在于计算下划线的位置,和下划线的动画效果。

// 根据当前选定的tab,得到indicator应该移动到的位置 private Pair<Float, Float> getIndicatorTargetLeftRight(int position, float positionOffset) { View tab = tabsContainer.getChildAt(position); Pair<Float, Float> indicator = getIndicatorLeftRight(tab); float targetLeft = indicator.first; float targetRight = indicator.second; // 如果positionOffset不为0,indicator正处于两个tab之间,需进行加权计算得到它的位置 if (positionOffset > 0f && position < tabCount - 1) { View nextTab = tabsContainer.getChildAt(position + 1); Pair<Float, Float> indicatorForNextTab = getIndicatorLeftRight(nextTab); float left = indicatorForNextTab.first; float right = indicatorForNextTab.second; targetLeft = (positionOffset * left + (1f - positionOffset) * targetLeft); targetRight = (positionOffset * right + (1f - positionOffset) * targetRight); } return new Pair<>(targetLeft, targetRight); } private Pair<Float, Float> getIndicatorLeftRight(View tab) { float left = tab.getLeft(); float right = tab.getRight(); if (indicatorMode == IndicatorMode.WRAP && tab instanceof TextView) { TextView tabTextView = (TextView) tab; paint.setTextSize(tabTextView.getTextSize()); float textLength = paint.measureText(tabTextView.getText().toString()); float middle = (left + right) / 2f; left = middle - textLength / 2f; right = middle + textLength / 2f; } return new Pair<>(left, right); }

上面是计算下划线位置的代码,通过传入在onPageScrolled()中获得的position和positionOffset,计算下划线是在某一个标签下,或者某两个标签之间的位置。需要注意的是,由于各标签的长度可能不一,所以下划线的长度在滑动中也可能发生变化,所以需分别计算下划线的left和right。

private boolean isAnimateRunning = false; private static final String TARGET_LEFT = "targetLeft"; private static final String TARGET_RIGHT = "targetRight"; private void startIndicatorAnimate(final float targetLeft, final float targetRight) { // 在indicator超出屏幕范围时,让其从屏幕边界处开始移动 float move = 0; if (indicatorCurrentRight < getScrollX()) { move = getScrollX() - indicatorCurrentRight; } else if (indicatorCurrentLeft > getScrollX() + DimenUtil.getScreenWidth(getContext())) { move = getScrollX() + DimenUtil.getScreenWidth(getContext()) - indicatorCurrentLeft; } indicatorCurrentLeft += move; indicatorCurrentRight += move; PropertyValuesHolder valuesHolderLeft = PropertyValuesHolder.ofFloat( TARGET_LEFT, indicatorCurrentLeft, targetLeft); PropertyValuesHolder valuesHolderRight = PropertyValuesHolder.ofFloat( TARGET_RIGHT, indicatorCurrentRight, targetRight); ValueAnimator animator = ValueAnimator.ofPropertyValuesHolder(valuesHolderLeft, valuesHolderRight) .setDuration(SCROLL_DURATION); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { if (indicatorCurrentLeft != targetLeft) { indicatorCurrentLeft = (float) animation.getAnimatedValue(TARGET_LEFT); } if (indicatorCurrentRight != targetRight) { indicatorCurrentRight = (float) animation.getAnimatedValue(TARGET_RIGHT); } if (indicatorCurrentLeft == targetLeft && indicatorCurrentRight == targetRight) { isAnimateRunning = false; } invalidate(); } }); animator.start(); isAnimateRunning = true; }

这是切换标签时下划线运行滑动动画的代码,使用ValueAnimator实现,并且对下划线超出边界的情况做了特殊处理,以防止滑动距离过大时,滑动速度过快。

更多的细节,请见https://github.com/wlkdb/page_sliding

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-10-11 23:46:52

Android实现网易严选标签栏滑动效果的相关文章

Android使用ViewPager实现无限滑动效果_Android

前言 其实仔细想一下原理还是挺简单的.无非是当我们滑动到最后一页,再向后滑动时定位到第一页;当我们滑动到第一页,再向前滑动时定位到最后一页. 但是,相信很多朋友都遇到过这个问题:视图的过度效果不自然. 小编也是通过百度和谷歌查找了很多解决方案,实验了很多方法,总结了一个相对不错的方法,接下来给各位分享下滑动效果.实现细节以及一些踩过的坑. 1.无限滑动效果(左右无限滑动) 事先准备好2张滑动图片(有想试验的小伙伴,自备图片啊,小编就不提供了...) 运行效果图(左右无限循环): 为了显示更加直观

Android view随触碰滑动效果

主要思路是通过父布局的onTouch(),方法,获取滑动到的位置和点击下的位置,再去设置子view的位置.我的代码中考虑了在边缘情况.需要注意的是,使用RelativeLayout,以imageView为例.从测试结果来看,bottomMargin 和rightMargin 性能非常差,最好还是用leftMargin与topMargin定位. 下面是运行效果: 布局文件里面就是一个Relativelayout中有一个ImageView.如下 <?xml version="1.0"

Android仿网易严选底部弹出菜单效果

在网易严选的看东西的时候在商品详情页里看到他的底部弹出菜单,本能反应是想用DottomSheetDialog或者PopupWindow来实现,可是发现实现不了他那种效果,于是就自己模仿一个像严选这样的底部弹出菜单. 不管是DottomSheetDialog或者PopupWindow他们的阴影背景都是全部覆盖的,这就造成除了菜单内容的View之外其他都是阴影的,而严选不是这样的.唠叨到此,首先展示效果图如下: 是不是还可以呢,由于代码量不多却注释详细,所以先贴出代码再一一详说: BottomPop

Android实现导航菜单左右滑动效果

今天给大家介绍在Android中实现顶部导航菜单左右滑动效果的二种解决方案. 第一种解决方案:  在以前的一篇博文中我使用android-support-v4.jar实现了左右滑动指引效果,有兴趣的朋友可以查看: http://www.cnblogs.com/hanyonglu/archive/2012/04/07/2435589.html    那么今天第一个示例我仍然使android-support-v4.jar来实现菜单左右滑动效果,关于这个包的信息,不再详述,大家可以查看官方文档. 实现

Android实现网易新闻客户端首页效果_Android

关于实现网易新闻客户端的界面,以前写过很多博客,请参考: Android实现网易新闻客户端效果 Android实现网易新闻客户端侧滑菜单(一) Android实现网易新闻客户端侧滑菜单(二) 今天用ViewPager + FragmentAdapter + ViewPagerIndicator来实现. ViewPagerIndicator是一款分页指标小部件兼容ViewPager,封装上做得非常不错,目前已为众多知名应用所使用.具体API的使用,大家可以下载官方demo示例研究研究就知道啦! 下

Android实现网易新闻客户端首页效果

关于实现网易新闻客户端的界面,以前写过很多博客,请参考: Android实现网易新闻客户端效果 Android实现网易新闻客户端侧滑菜单(一) Android实现网易新闻客户端侧滑菜单(二) 今天用ViewPager + FragmentAdapter + ViewPagerIndicator来实现. ViewPagerIndicator是一款分页指标小部件兼容ViewPager,封装上做得非常不错,目前已为众多知名应用所使用.具体API的使用,大家可以下载官方demo示例研究研究就知道啦! 下

Android实现探探图片滑动效果

之前一段时间,在朋友的推荐下,玩了探探这一款软件,初玩的时候,就发现,这款软件与一般的社交软件如陌陌之类的大相径庭,让我耳目一新,特别是探探里关于图片滑动操作让人觉得非常新鲜.所以在下通过网上之前的前辈的经历加上自己的理解,也来涉涉水.下面是网上找的探探的原界面 当时就非常想通过自己来实现这种仿探探式的效果,然而却没什么思路.不过毋庸置疑的是,这种效果的原理肯定和 ListView /RecyclerView 类似,涉及到 Item View 的回收和重用,否则早就因为大量的 Item View

Android实现左右滑动效果的方法详解_Android

本示例演示在Android中实现图片左右滑动效果. 关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来就让我们开始实现这种效果.为了方便大家理解,我们先来看一下效果图:主要效果图如下图:    接下来我们看一下程序结构图: MainActivity文件中代码: 复制代码 代码如下: package com.android.flip;import android.app.Activity;import a

Android实现左右滑动效果的方法详解

本示例演示在Android中实现图片左右滑动效果. 关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来就让我们开始实现这种效果.为了方便大家理解,我们先来看一下效果图:主要效果图如下图: 接下来我们看一下程序结构图: MainActivity文件中代码:复制代码 代码如下:package com.android.flip;import android.app.Activity;import androi