Android自定义横线滑动折线图,点击,加载更多

项目地址:https://github.com/604982372/HorizontalLine

实现步骤:

1.设置属性;

2.绘制内容;

3.处理滑动事件;

4.添加选中,滑动更多功能。

设置属性

1.在attrs.xml文件中添加设置:

 

<declare-styleable name="HorizontalLineView">
        <attr name="linecolor" format="color"/>
        <attr name="textsizedefault"  format="dimension"/>
        <attr name="textsizeselected"  format="dimension"/>
        <attr name="textcolorselected" format="color"/>
        <attr name="textcolordefault" format="color"/>
        <attr name="bg" format="color"/>
    </declare-styleable>

2.初始化画笔,折线图画笔,线上数字画笔,x轴文字画笔

private void initPaint()
    {
        mValueTextPaint = new Paint();
        mValueTextPaint.setAntiAlias(true);
        mValueTextPaint.setTextSize(mTextSizeDefault);
        //mValueTextPaint.setStrokeCap(Paint.Cap.ROUND);
        mValueTextPaint.setColor(mTextColorSelected);
        //mValueTextPaint.setStyle(Paint.Style.STROKE);
        mValueTextPaint.setStyle(Paint.Style.FILL);

        mXTextPaint = new Paint();
        mXTextPaint.setAntiAlias(true);
        mXTextPaint.setTextSize(mTextSizeDefault);
        //mValueTextPaint.setStrokeCap(Paint.Cap.ROUND);
        mXTextPaint.setColor(getColor(R.color.orange));
        //mValueTextPaint.setStyle(Paint.Style.STROKE);
        mXTextPaint.setStyle(Paint.Style.FILL);

        mLinePaint = new Paint();
        mLinePaint.setAntiAlias(true);
        mLinePaint.setStrokeCap(Paint.Cap.ROUND);
        mLinePaint.setColor(mLinecolor);
        mLinePaint.setStyle(Paint.Style.FILL);
        mLinePaint.setStrokeWidth(dpToPx(1.3f));
    }

绘制内容,绘制点,线,文字

 

for (int i = 0; i < mValueTotalList.size(); i++)
        {
            if (maxValue < mValueTotalList.get(i))
            {
                maxValue = mValueTotalList.get(i);
            }
        }
        for (int i = 0; i < mValueTotalList.size(); i++)
        {
            float valuei = (maxValue - mValueTotalList.get(i)) * mMeasureHeight / maxValue + xValueTextHeight + mPaddingTop;
            String testString = String.valueOf(mValueTotalList.get(i));
            mValueTextPaint.setColor(mIsSelected == i ? mTextColorSelected : mTextColorDefault);
            mXTextPaint.setColor(mIsSelected == i ? mTextColorSelected : mTextColorDefault);
            mValueTextPaint.setTextSize(mIsSelected == i ? mTextSizeSelected : mTextSizeDefault);
            Rect bounds = getTextBounds(testString, mValueTextPaint);
            Rect bou = getTextBounds(mXValueList.get(i), mValueTextPaint);
            canvas.drawText(mXValueList.get(i),
                    mMeasureWidth / 10 + i * mMeasureWidth / 5 - bou.width() / 2, mMeasureHeight + 2 * xValueTextHeight + mPaddingTop,
                    mXTextPaint);

            if (i == 0)
            {
                canvas.drawCircle(mMeasureWidth / 10, valuei, dpToPx(3.5f), mLinePaint);
                canvas.drawText(testString, mMeasureWidth / 10 - bounds.width() / 2, valuei - mTextdistancePoint, mValueTextPaint);
            }
            else
            {
                float valuei1 = (maxValue - mValueTotalList.get(i - 1)) * mMeasureHeight / maxValue + xValueTextHeight + mPaddingTop;
                canvas.drawLine(mMeasureWidth / 10 + (i - 1) * mMeasureWidth / 5, valuei1
                        , mMeasureWidth / 10 + i * mMeasureWidth / 5, valuei, mLinePaint);// 画线
                canvas.drawCircle(mMeasureWidth / 10 + i * mMeasureWidth / 5, valuei, dpToPx(3.5f), mLinePaint);
                Log.v("3699318", bounds.width() + "");
                canvas.drawText(testString,
                        mMeasureWidth / 10 + i * mMeasureWidth / 5 - bounds.width() / 2, valuei - mTextdistancePoint,
                        mValueTextPaint);
            }
        }

处理滑动事件,添加选中,右滑加载更多功能

 

@Override
    public boolean onTouchEvent(MotionEvent event)
    {
        if (mVelocityTracker == null)
        {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                mTouchX = (int) event.getX();
                mTouchY = (int) event.getY();
                mMoveX = mTouchX;
                return true;

            case MotionEvent.ACTION_MOVE:
                if (monthLineWidth > mMeasureWidth)
                {
                    int dx = (int) event.getX() - mMoveX;
                    if (dx > 0)
                    { // 右滑
                        Log.v("3699右滑", "********" + mScroller.getFinalX());
                        if (mScroller.getFinalX() > 0)
                        {
                            mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), -dx, 0, 400);
                        }
                        else
                        {
                            mScroller.setFinalX(0);
                            if (mIOnScrollStateListener != null && !mIsScrollBottom)
                            {
                                Log.v("3699加载185", "0000000000000");
                                mIsScrollBottom = true;
                                mIOnScrollStateListener.onScrollbottom();
                            }
                        }
                    }
                    else
                    { //左滑
                        Log.v("3699左滑", "---------" + (mScroller.getFinalX() + mMeasureWidth - dx < monthLineWidth) + "++++" + monthLineWidth +
                                "·······" + (mScroller.getFinalX() + mMeasureWidth - dx));
                        if (mScroller.getFinalX() + mMeasureWidth - dx < monthLineWidth)
                        {
                            mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), -dx, 0, 400);
                        }
                        else
                        {
                            mScroller.setFinalX(monthLineWidth - mMeasureWidth);
                        }
                    }
                    mMoveX = (int) event.getX();
                    invalidate();
                }
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (monthLineWidth > mMeasureWidth)
                {
                    final MotionEvent vtev = MotionEvent.obtain(event);
                    final ViewConfiguration vc = ViewConfiguration.get(getContext());
                    mTouchSlop = vc.getScaledTouchSlop();
                    mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
                    mVelocityTracker.addMovement(vtev);
                    mVelocityTracker.computeCurrentVelocity(1000, mMaxFlingVelocity);
                    int max = Math.max(Math.abs(mScroller.getCurrX()), Math.abs(monthLineWidth - mMeasureWidth - mScroller.getCurrX()));
                    mIsStop = false;
                    mScroller.fling(mScroller.getFinalX(), mScroller.getFinalY()
                            , (int) -mVelocityTracker.getXVelocity(), (int) -mVelocityTracker.getYVelocity(),
                            0, monthLineWidth - mMeasureWidth, mScroller.getFinalY(), mScroller.getFinalY());
                    //手指抬起时,根据滚动偏移量初始化位置
                    float lv = ((mScroller.getFinalX() - mMeasureWidth / 10) * 1.00f) / (mMeasureWidth / 5);
                    Log.v("3699max", max + "*****" + mScroller.getCurrX() + "--->" + ((int) lv) * mMeasureWidth / 5 + "-----lv>" + lv
                            + "   getFinalX:" + mScroller.getFinalX());
                    Log.v("3699lv", lv - ((int) lv) + "");

                    if (mScroller.getFinalX() < 0)
                    {
                        Log.v("3699145", "1451451545145");
                        mScroller.abortAnimation();
                        mScroller.startScroll(mScroller.getCurrX(), mScroller.getCurrY(), -mScroller.getCurrX(), 0, 400);
                    }
                    else if (mScroller.getFinalX() > monthLineWidth - mMeasureWidth)
                    {
                        Log.v("3699145", "151151151151151");
                        mScroller.abortAnimation();
                        mScroller.startScroll(mScroller.getCurrX(), mScroller.getCurrY(), monthLineWidth - mMeasureWidth - mScroller.getCurrX(), 0, 400);
                    }
                }
                if (event.getAction() == MotionEvent.ACTION_UP)
                {
                    mIsScrollBottom = false;
                    Log.v("3699up", "***" + mScroller.getFinalX());
                    int mUpX = (int) event.getX();
                    int mUpY = (int) event.getY();
                    //模拟点击操作
                    if (Math.abs(mUpX - mTouchX) <= mTouchSlop && Math.abs(mUpY - mTouchY) <= mTouchSlop)
                    {
                        for (int i = 0; i < mValueTotalList.size(); i++)
                        {
                            if (Math.abs((mScroller.getCurrX() + mUpX) - (mMeasureWidth / 10 + (i * mMeasureWidth / 5))) <= 15)
                            {
                                setSelected(i);
                                Log.v("3699点击", "" + i);
                                return super.onTouchEvent(event);
                            }
                        }
                    }
                }
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }

滑动完成监听

 

@Override
    public void computeScroll()
    {
        //先判断mScroller滚动是否完成
        if (mScroller.computeScrollOffset())
        {
            //这里调用View的scrollTo()完成实际的滚动
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            //必须调用该方法,否则不一定能看到滚动效果
            postInvalidate();
        }
        if (mScroller.isFinished() && !mIsStop)
        {
            mIsStop = true;
            int lv = mScroller.getFinalX() % (mMeasureWidth / 5);
            int n = mScroller.getFinalX() / (mMeasureWidth / 5);

            Log.v("3699停止", mScroller.getCurrX() + "    " + mScroller.getFinalX() + "      " + mMeasureWidth / 5 + "   lv:" + lv);
            //if (Math.abs(lv - ((int) lv)) < 0.1)
            {
                mScroller.abortAnimation();
                if (lv > mMeasureWidth / 10)//+
                {
                    mScroller.startScroll(mScroller.getFinalX(), mScroller.getCurrY(),
                            (mMeasureWidth / 5 - lv), 0, 400);
                    if (mIOnScrollStateListener != null)
                    {
                        mIOnScrollStateListener.onScrollStop(n + 1);
                    }
                }
                else
                {
                    mScroller.startScroll(mScroller.getFinalX(), mScroller.getCurrY(),
                            -lv, 0, 400);
                    if (mIOnScrollStateListener != null)
                    {
                        mIOnScrollStateListener.onScrollStop(n);
                    }
                }
            }
        }
        super.computeScroll();
    }

项目地址:https://github.com/604982372/HorizontalLine

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可能是因为你使用了平滑曲线(smooth)的选项,这会在折线图的起始点和结束点处生成一条横线,以平滑曲线的方式连接起始点和结束点。如果你不想要这条横线,可以将 smooth 设置为 false。例如: ```javascript option = { xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [{ data: [820, 932, 901, 934, 1290, 1330, 1320], type: 'line', smooth: false // 关闭平滑曲线 }] }; ``` 这样就不会再出现多余的横线了。 ### 回答2: 当我们使用ECharts折线图时,出现多出一条横线的情况可能是我们在数据的数组中多了一个多余的值,导致折线图数据点的个数与x轴刻度的个数不一致。 首先,我们需要检查数据数组的长度和x轴刻度的个数是否匹配。例如,如果x轴刻度有5个,那么对应的数据数组应该也有5个数据点。如果数据数组中多了一个数据点,就会导致折线图绘制出多出一条横线的情况。 其次,我们也需要检查数据数组中是否存在重复的值。如果数据数组中有重复的值,ECharts在绘制折线图时会将这些重复的值视为连续的数据点,从而导致多出一条横线。 另外,还需要注意检查代码中是否有误操作导致数据数组中多了一个不需要的值。例如,在循环中误多添加了一个数据点,或者在数据处理过程中出现了错误。 综上所述,当ECharts折线图时多出一条横线的情况,可能是数据数组的长度与x轴刻度的个数不匹配,存在重复的值,或者代码中出现了误操作。我们需要仔细检查数据数组和代码,确保数据的准确性和匹配性,以解决这个问题。 ### 回答3: ECharts 是一个开源的数据可视化库,用于绘制各种类型的图表,包括折线图。如果在使用 ECharts折线图时,出现了多出一条横线的情况,可能是由于以下原因导致的: 1. 数据错误:首先要检查传入的数据是否正确。在绘制折线图时,要确保传入的数据是按照正确的格式进行组织,如数组等。如果数据格式有误,可能会导致绘制出的图表出现异常情况,包括多出一条横线。 2. 数据重复:如果传入的数据中存在重复的值,可能会导致绘制的折线图多出一条横线。因为折线图是通过连接数据点来绘制的,如果存在重复的数据点,绘制时会造成多余的线段。 3. 绘制配置错误:在使用 ECharts 绘图时,需要正确配置各种参数来实现预期的效果。如果配置参数错误,可能会导致折线图的绘制出现异常情况。可以检查是否对折线图的绘制参数进行了错误的配置,如多配置了一条横线。 4. 绘图组件错误:ECharts 是基于 Canvas 或 SVG 进行绘制的,如果使用的绘图组件有问题,也可能导致绘制出的折线图多出一条横线。可以尝试重新安装或更新绘图组件,并重新绘制折线图。 在遇到折线图多出一条横线的问题时,可以通过仔细检查数据和配置参数,并尝试调整绘图组件来解决。如果问题持续存在,可以参考 ECharts 的官方文档或寻求技术支持来获得更准确的解答。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值