标签栏是一个非常常见的控件,似乎也是一个比较简单的控件,但如果在标签下方加个下划线的话,就还是可以玩出挺多花来的。
网易严选的标签栏就做的很不错,里面隐藏着诸多细节:
仔细分析下,需要在简单标签栏的基础上实现以下逻辑:
我做了一个样例程序,其中的较难点在于计算下划线的位置,和下划线的动画效果。
// 根据当前选定的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实现标签栏功能(只支持固定两个标签)
# 下划线
# 的是
# 这是
# 左端
# 是在
# 会有
# 基础上
# 很不错
# 网易
# 不为
# 中也
# 过大
# 过快
# 正处于
# 是一个非常
# 时下
# 画出
# 就做
# 需要注意
# 让其
相关文章:
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?
广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?
如何通过VPS建站无需域名直接访问?
较简单的网站制作软件有哪些,手机版网页制作用什么软件?
php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】
广州商城建站系统开发成本与周期如何控制?
武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?
建站之星如何实现网站加密操作?
建站之星会员如何解锁更多建站功能?
如何基于云服务器快速搭建网站及云盘系统?
学校建站服务器如何选型才能满足性能需求?
,网页ppt怎么弄成自己的ppt?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
如何配置IIS站点权限与局域网访问?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
如何用已有域名快速搭建网站?
香港服务器网站卡顿?如何解决网络延迟与负载问题?
建站之星好吗?新手能否轻松上手建站?
建站主机数据库如何配置才能提升网站性能?
建站主机功能解析:服务器选择与快速搭建指南
如何在建站主机中优化服务器配置?
高防服务器租用如何选择配置与防御等级?
如何在IIS中新建站点并解决端口绑定冲突?
建站主机选择指南:服务器配置与SEO优化实战技巧
如何实现建站之星域名转发设置?
网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?
网站制作公司,橙子建站是合法的吗?
装修招标网站设计制作流程,装修招标流程?
简易网站制作视频教程,使用记事本编写一个简单的网页html文件?
电商网站制作价格怎么算,网上拍卖流程以及规则?
如何快速辨别茅台真假?关键步骤解析
南宁网站建设制作定制,南宁网站建设可以定制吗?
网站制作需要会哪些技术,建立一个网站要花费多少?
公众号网站制作网页,微信公众号怎么制作?
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
南京网站制作费用,南京远驱官方网站?
安云自助建站系统如何快速提升SEO排名?
建站主机服务器选购指南:轻量应用与VPS配置解析
如何快速生成凡客建站的专业级图册?
深圳 网站制作,深圳招聘网站哪个比较好一点啊?
如何快速配置高效服务器建站软件?
如何将凡科建站内容保存为本地文件?
如何在万网自助建站平台快速创建网站?
青岛网站建设如何选择本地服务器?
如何用VPS主机快速搭建个人网站?
小程序网站制作需要准备什么资料,如何制作小程序?
网站制作大概多少钱一个,做一个平台网站大概多少钱?
javascript中对象的定义、使用以及对象和原型链操作小结
如何选择适合PHP云建站的开源框架?
*请认真填写需求信息,我们会在24小时内与您取得联系。