67.220.91.30最新,升降机租赁,丘芷蓉
标签栏是一个非常常见的控件,似乎也是一个比较简单的控件,但如果在标签下方加个下划线的话,就还是可以玩出挺多花来的。
网易严选的标签栏就做的很不错,里面隐藏着诸多细节:
仔细分析下,需要在简单标签栏的基础上实现以下逻辑:
我做了一个样例程序,其中的较难点在于计算下划线的位置,和下划线的动画效果。
// 根据当前选定的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实现,并且对下划线超出边界的情况做了特殊处理,以防止滑动距离过大时,滑动速度过快。
更多的细节,请见
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Android studio开发小型对话机器人app(实例代码)
Android通过Java sdk的方式接入OpenCv的方法
Android 通过cmake的方式接入opencv的方法步骤
Android Studio finish()方法的使用与解决app点击“返回”(直接退出)
Android 进度条 ProgressBar的实现代码(隐藏、出现、加载进度)
网友评论