自定义view股票分时图+惯性滑动效果

已经将近一个月没有项目做了,闲着没事,刚好这块知识点有点模糊不清,所以特意复习了一下整理了一个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

 

原文链接:加载失败,请重新获取