已经将近一个月没有项目做了,闲着没事,刚好这块知识点有点模糊不清,所以特意复习了一下整理了一个demo,主要知识点是惯性滑动,overScrooler配合filing以及paint,path,canvas的使用,先看下效果图吧
这里我主要分成了4个类画蜡烛图,画折线图,画直线图,以及画文字,如果嫌弃类多的可以自己整合一下,先来说一下滑动overScrooler配合filing的使用,滑动这一块有两种方式可以实现,一个是Scrooler一个是overScrooler,overScrooler比较全面,比Scrooler多了几个方法,更能满足开发者的需求,谷歌推荐使用overScrooler,既然说了是惯性滑动,那么肯定是有一个初速度的,这里官方给我们提供了一个专门获取速度的类,VelocityTracker,不明白的可以去百度一下,看以下代码。
@Override
public boolean onTouchEvent(MotionEvent event){
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
super.onTouchEvent(event);
//手指位置地点
float x = event.getX();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
// //如果屏幕的动画还没结束,你就按下了,我们就结束该动画
if(mScroller != null){
if(!mScroller.isFinished()){
mScroller.abortAnimation();
}
}
mLastionMotionX = x ;
break ;
case MotionEvent.ACTION_MOVE:
int detaX = (int)(mLastionMotionX - x );
if(scroolWidth<(measuredWidth)&&scroolWidth>0){
scrollBy(detaX, 0);
}
mLastionMotionX = x ;
break ;
case MotionEvent.ACTION_UP:
final VelocityTracker velocityTracker = mVelocityTracker ;
velocityTracker.computeCurrentVelocity(1000);
velocityX = (int) velocityTracker.getXVelocity() ;
snapToScreen();
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true ;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
scroolWidth=l;
}
private void snapToScreen(){
synchronized (ChartLineView.this) {
mScroller.fling(Math.round(getScrollX()), top, -Math.round(velocityX),0, 0, measuredWidth, 0, Integer.MAX_VALUE);
}
postInvalidate();
}
当我们手抬起的时候就获取它的速度,调用snapToScreen(),进行惯性滑动,这里稍微有一个地方需要注意一下,在我们调用了
fling这个方法后一定要刷新view,不然是看不到效果的,然后去重写computeScroll这个方法
@Override
public void computeScroll() {
// TODO Auto-generated method stub
Log.e(TAG, "computeScroll");
// 如果返回true,表示动画还没有结束
// 因为前面startScroll,所以只有在startScroll完成时 才会为false
if (mScroller.computeScrollOffset()) {
// 产生了动画效果 每次滚动一点
scrollTo(mScroller.getCurrX(), 0);
//刷新View 否则效果可能有误差
postInvalidate();
}
}
滑动就这些内容,如果你看过ScroolView源码的话那么这一块就很容易懂了,下面讲解一下画分时图,因为分时图不仅有折线图而且还带了下面的阴影部分,颜色都是完全不一样的,所以我这里用了两个Paint和Path,一个画折线,一个画阴影,这里我讲解一下主要的两个方法,第一个是lineTo,这个方法是连接终点x,y的坐标,起点就是上一个点,还有一个方法是moveTo,这个方法就是初始化起点的位置,最后通过canvas.drawPath绘制出来就可以了,主要代码如下
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawLine(canvas);
}
public void setData(List<DateBean> list){
synchronized(list){
this.list=list;
}
invalidate();
}
private void drawLine(Canvas canvas) {
Path mPath = new Path();
Path mPath2 = new Path();
mPath.moveTo(left,top);
mPath2.moveTo(left,top);
for (int i=0;i<list.size();i++){
mPath.lineTo(left+list.get(i).getX(),top-list.get(i).getY());
mPath2.lineTo(left+list.get(i).getX(),top-list.get(i).getY());
}
measuredWidth=list.get(list.size()-1).getX()-getMeasuredWidth();
mPath2.lineTo(left+list.get(list.size()-1).getX(),top);
canvas.drawPath(mPath,paint);
canvas.drawPath(mPath2,mBrokenLineBgPaint);
}
分时图其实很简单,知识点也很少,至于画虚线和文字都大同小异,上面的理解了就不是难事。源码地址:https://download.csdn.net/download/qq_33407981/10558964