标签栏是一个非常常见的控件,似乎也是一个比较简单的控件,但如果在标签下方加个下划线的话,就还是可以玩出挺多花来的。
网易严选的标签栏就做的很不错,里面隐藏着诸多细节:
仔细分析下,需要在简单标签栏的基础上实现以下逻辑:
我做了一个样例程序,其中的较难点在于计算下划线的位置,和下划线的动画效果。
// 根据当前选定的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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Android
# 标签栏
# 滑动
# Android Navigation TabBar控件实现多彩标签栏
# android配合viewpager实现可滑动的标签栏示例分享
# Android View教程之自定义验证码输入框效果
# Android自定义View实现课程表表格
# Android自定义view实现圆的扩散效果
# Android自定义view实现标签栏功能(只支持固定两个标签)
# 下划线
# 的是
# 这是
# 左端
# 是在
# 会有
# 基础上
# 很不错
# 网易
# 不为
# 中也
# 过大
# 过快
# 正处于
# 是一个非常
# 时下
# 画出
# 就做
# 需要注意
# 让其
相关文章:
如何快速搭建高效WAP手机网站?
如何配置WinSCP新建站点的密钥验证步骤?
阿里云网站制作公司,阿里云快速搭建网站好用吗?
如何通过多用户协作模板快速搭建高效企业网站?
如何注册花生壳免费域名并搭建个人网站?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
TestNG的testng.xml配置文件怎么写
台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?
实惠建站价格推荐:2025年高性价比自助建站套餐解析
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
如何在建站宝盒中设置产品搜索功能?
如何用低价快速搭建高质量网站?
Android使用GridView实现日历的简单功能
高防服务器租用指南:配置选择与快速部署攻略
网站制作话术技巧,网站推广做的好怎么话术?
如何在IIS中配置站点IP、端口及主机头?
广州网站建站公司选择指南:建站流程与SEO优化关键词解析
西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?
网站制作哪家好,cc、.co、.cm哪个域名更适合做网站?
详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
如何通过WDCP绑定主域名及创建子域名站点?
建站VPS推荐:2025年高性能服务器配置指南
如何使用Golang table-driven基准测试_多组数据测量函数效率
建站之星免费模板:自助建站系统与智能响应式一键生成
英语简历制作免费网站推荐,如何将简历翻译成英文?
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
内部网站制作流程,如何建立公司内部网站?
网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?
如何在Golang中使用encoding/gob序列化对象_存储和传输数据
宝塔建站教程:一键部署配置流程与SEO优化实战指南
电商网站制作价格怎么算,网上拍卖流程以及规则?
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
宝塔建站后网页无法访问如何解决?
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
制作旅游网站html,怎样注册旅游网站?
油猴 教程,油猴搜脚本为什么会网页无法显示?
建站主机选哪家性价比最高?
建站之星后台密码如何安全设置与找回?
如何选择网络建站服务器?高效建站必看指南
建站org新手必看:2024最新搭建流程与模板选择技巧
网站制作网站,深圳做网站哪家比较好?
如何在万网ECS上快速搭建专属网站?
定制建站流程解析:需求评估与SEO优化功能开发指南
代购小票制作网站有哪些,购物小票的简要说明?
如何安全更换建站之星模板并保留数据?
建站之星如何修改网站生成路径?
专业公司网站制作公司,用什么语言做企业网站比较好?
制作网站的过程怎么写,用凡科建站如何制作自己的网站?
如何通过虚拟机搭建网站?详细步骤解析
*请认真填写需求信息,我们会在24小时内与您取得联系。