插件比较复杂,先描述下功能。
1.可横向滚动
2.数值可自定义。
3.要求有三角指示器,指向当前焦点
4.点击后焦点改变,并且三角指示器可滑动变化
5.焦点滚动至最左或最右时不消失(这里使用新的view获取焦点view的值悬浮显示,滚动条中的view已经还是滚动消失了)
上效果图,上面使用ImageView作为子View,下面使用TextView作为子View。
布局说明:
1.底部滚动条TimeBar继承自HorizontalScrollView,在onDraw()中添加三角指示器(三角滑块)绘制代码,使指示器随焦点滑动。
@Override public void onDraw(Canvas canvas) { super.onDraw(canvas); //Log.d("Validated!", "Should not always validate"); if (mSelectedView != null){ int step = getWidth()/30; canvas.drawColor(Color.BLACK); paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.LTGRAY); paint.setStyle(Paint.Style.FILL); if (curTriangle == null){ curTriangle = new Triangle( mSelectedView.getLeft() + mSelectedView.getWidth()/2 - 10, mSelectedView.getTop() - 4, mSelectedView.getLeft() + mSelectedView.getWidth()/2 + 10, mSelectedView.getTop() + 13.3f ); } if (tarTriangle == null){ tarTriangle = new Triangle( mSelectedView.getLeft() + mSelectedView.getWidth()/2 - 10, mSelectedView.getTop() - 4, mSelectedView.getLeft() + mSelectedView.getWidth()/2 + 10, mSelectedView.getTop() + 13.3f ); } if (Math.abs(curTriangle.left - tarTriangle.left) < step) { curTriangle.left = tarTriangle.left; curTriangle.right = tarTriangle.right; curTriangle.reDraw(); } if (curTriangle.left > tarTriangle.left){ curTriangle.left -= step; curTriangle.right -= step; curTriangle.reDraw(); invalidate(); } else if (curTriangle.left < tarTriangle.left) { curTriangle.left += step; curTriangle.right += step; curTriangle.reDraw(); invalidate(); } canvas.drawPath(curTriangle.getPath(), paint); } } }
2.左右各添加一个TimePanel,继承自LinearLayout,重载onDraw()方法, 绘制出三角指示器,相对于上面的绘制代码较简单,不需要处理滑动情况,仅绘制出三角即可。
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.BLACK); paint.setColor(Color.LTGRAY); paint.setStyle(Paint.Style.FILL); if (curTriangle == null){ curTriangle = new Triangle( mTextView.getLeft() + mTextView.getWidth()/2 - 10, mTextView.getTop() - 4, mTextView.getLeft() + mTextView.getWidth()/2 + 10, mTextView.getTop() + 13.3f ); } canvas.drawPath(curTriangle.getPath(), paint); }
3.TimePicker作为一个容器,容纳TimeBar和左右各一的TimePanel,重载onDraw()方法,在其中加入TimePanel显示和隐藏的判断条件。
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int x = timeBar.getScrollX(); focusedBtn = (TextView)timeBar.getSelectedView(); if (focusedBtn != null){ if (focusedBtn.getLeft() - x < 0){ ((TextView)timePanelLeft.getChildTextView()).setText(focusedBtn.getText()); timePanelLeft.setVisibility(View.VISIBLE); timePanelRight.setVisibility(View.GONE); } else if (focusedBtn.getRight() - x > getWidth()){ ((TextView)timePanelRight.getChildTextView()).setText(focusedBtn.getText()); timePanelRight.setVisibility(View.VISIBLE); timePanelLeft.setVisibility(View.GONE); } else{ timePanelRight.setVisibility(View.GONE); timePanelLeft.setVisibility(View.GONE); } } }
4.仍需重载TimePicker中的dispatchTouchEvent (ev),将点击事件传递给timeBar,否则会发现timeBar无法响应点击事件。
@Override public boolean dispatchTouchEvent(MotionEvent ev) { timeBar.onTouchEvent(ev); return super.dispatchTouchEvent(ev); }
源码:https://files.cnblogs.com/feifei1010/BottomBar.rar
欢迎关注微博:http://e.weibo.com/u/2975543812