一条线的折线图实现 android




package com.stategrid.echarge.wedgit.chart;

import android.content.Context;
import android.graphics.Canvas;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.stategrid.echarge.R;

import java.util.ArrayList;

/**
 * 单线图
 */
public class SingleFlogLineChart extends RelativeLayout {

    private Context mContext;

    private ArrayList<String> unitArrayList;
    private UnitAdapter adapter;
    private double itemWidth;
    private LinearLayoutManager manager;
    private boolean canRecyclScoll = false;
    private ArrayList<PointBean> firstPointBeans;
    private double unitItemWidth;

    private PointBean maxYPoint;


    public SingleFlogLineChart(Context context) {
        this(context, null);
    }

    public SingleFlogLineChart(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SingleFlogLineChart(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
    }

    public void setCanRecyclScoll(boolean canRecyclScoll) {
        this.canRecyclScoll = canRecyclScoll;
    }

    public void setUnitArrayList(ArrayList<String> arrayList) {
        this.unitArrayList = arrayList;
        adapter.setArrayList(unitArrayList);
        adapter.notifyDataSetChanged();

    }

    private RecyclerView unitRv;
    private LineRelativeLayout lineRelativeLayout;

    private SingleLineContainerView lineContainerView;


    private TextView leftTopTitle;
    private TextView rightTopTile;


    /**
     * set leftTitle
     *
     * @param leftTitle
     */
    public void setLeftTopTitle(String leftTitle) {
        leftTopTitle.setText(leftTitle);
    }

    /**
     * set rightTitle
     *
     * @param rightTitle
     */
    public void setRightTopTitle(String rightTitle) {
        rightTopTile.setText(rightTitle);
    }


    public void setFirstPointBeans(ArrayList<PointBean> firstPointBeans) {
        lineContainerView.setFirstPoints(firstPointBeans);
        this.firstPointBeans = firstPointBeans;
    }

    private LinearLayout bottomUnitLayout;
    private RecyclerView LeftUnitRv;
    private ObserverHorizontalScrollview scrollView;

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        unitRv = findViewById(R.id.bottom_unit_rv);
        lineRelativeLayout = findViewById(R.id.chart_rl);
        scrollView = findViewById(R.id.horizon_scrollview);
        lineContainerView = findViewById(R.id.line_container_layout);
        bottomUnitLayout = findViewById(R.id.unit_llayout);
        LeftUnitRv = findViewById(R.id.left_unit_rv);
        manager = new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false) {
            @Override
            public boolean canScrollHorizontally() {
                return canRecyclScoll;
            }
        };
        unitRv.setLayoutManager(manager);

        LinearLayoutManager leftManager = new LinearLayoutManager(mContext) {
            @Override
            public boolean canScrollVertically() {
                return false;
            }
        };

        LeftUnitRv.setLayoutManager(leftManager);


        scrollView.setmScrollViewListener(new ObserverHorizontalScrollview.ScrollViewListener() {

            private int sum;

            @Override
            public void onScrollChanged(int x, int y, int oldx, int oldy) {

            }

            @Override
            public void onScrollFinish(int scrollX) {
                canRecyclScoll = true;
                sum = (int) (scrollX / itemWidth);
                int halfItemWidth = (int) (itemWidth / 2);
                if (scrollX - itemWidth * sum > halfItemWidth) {
                    sum++;
                }

                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.scrollTo((int) (itemWidth * sum), 0);

                    }
                }, 50);
//
                int firstItem = manager.findFirstVisibleItemPosition();
                int lastItem = manager.findLastVisibleItemPosition();

                Log.e("sum:", "" + sum + "--last--" + firstItem);


                //然后区分情况
                if (sum <= firstItem) {
                    //当要置顶的项在当前显示的第一个项的前面时
                    unitRv.scrollToPosition(sum);
                } else if (sum <= lastItem) {
                    //当要置顶的项已经在屏幕上显示时,计算它离屏幕原点的距离
                    int left = unitRv.getChildAt(sum - firstItem).getLeft();
                    unitRv.scrollBy(left, 0);
                } else {
                    //当要置顶的项在当前显示的最后一项的后面时
                    unitRv.scrollToPosition(sum + 6);
                    //记录当前需要在RecyclerView滚动监听里面继续第二次滚动
                }


                maxYPoint = null;
                //设置最大点的位置
                int position = sum;
                for (int i = sum; i <= sum + 6; i++) {
                    if (maxYPoint == null) {
                        maxYPoint = firstPointBeans.get(i);
                    } else {
                        if (maxYPoint.getPercentY() < firstPointBeans.get(i).getPercentY()) {
                            maxYPoint = firstPointBeans.get(i);
                            position = i;
                        }
                    }
                }

                lineContainerView.setMaxPoint(maxYPoint);
                if (position == sum) {
                    lineContainerView.setPosition(SingleLineContainerView.BITMAP_LEFT);
                } else if (position == sum + 6) {
                    lineContainerView.setPosition(SingleLineContainerView.BITMAP_RIGHT);
                } else {
                    lineContainerView.setPosition(SingleLineContainerView.BITMAP_MID);
                }

                lineContainerView.invalidate();

                canRecyclScoll = false;
            }
        });


        leftTopTitle = findViewById(R.id.left_top_title);
        rightTopTile = findViewById(R.id.right_top_title);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        int width = lineRelativeLayout.getMeasuredWidth();
        itemWidth = width * 1.00 / 6;

        unitItemWidth = itemWidth - 5;

        unitRv.getLayoutParams().width = (int) (unitItemWidth * 7);

        Log.d("itemWidth-", itemWidth + "");

        unitArrayList = new ArrayList<>();
        for (int i = 1; i < 10; i++) {
            double num = 5 + i * 0.01;
            unitArrayList.add(num + "");
        }

        for (int i = 10; i < 31; i++) {
            double num = 5 + i * 0.01;
            unitArrayList.add(num + "");
        }

        adapter = new UnitAdapter(mContext, unitArrayList, unitItemWidth);
        unitRv.setAdapter(adapter);
//        unitRv.getLayoutParams().width = (int) (itemWidth*7);


        int height = LeftUnitRv.getMeasuredHeight();
//        Log.d("height:", height + "");

        double itemHeight = height * 1.0 / 7;

        ArrayList<String> leftList = new ArrayList<>();

        for (int i = 70; i >= 10; i = i - 10) {
            leftList.add(i + "");
        }

        LeftUnitAdapter leftUnitAdapter = new LeftUnitAdapter(mContext, leftList, itemHeight);
        LeftUnitRv.setAdapter(leftUnitAdapter);


//        firstPointBeans = new ArrayList<>();
//
//        Random random = new Random();
//        for (int i = 0; i <= 30; i++) {
//            int percentY = (random.nextInt(4) + 2) * 10 - 2;
//            PointBean pointBean = new PointBean(i*0.2, percentY);
//            firstPointBeans.add(pointBean);
//        }
//
//
//        lineContainerView.setWidth((int) (itemWidth * 20));
//        lineContainerView.setItemWidth(itemWidth);
//        lineContainerView.setFirstPoints(firstPointBeans);
//        lineContainerView.setFirstColor(Color.parseColor("#a1ffdd"));
////        lineContainerView.setFirstColor(Color.RED);
////        lineContainerView.setTextColor(Color.RED);
//        lineContainerView.invalidate();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);


    }
}
 
 

   //工具类

package com.stategrid.echarge.wedgit.chart;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;

import com.stategrid.echarge.R;

import java.util.ArrayList;

public class SingleLineContainerView extends AppCompatTextView {

    private Context mContext;

    private Paint firstLinePaint;

    private Paint textPaint;

    private double itemWidth;

    private String str = "60";

    private ArrayList<PointBean> firstPoints;

    private PointBean maxPoint;

    private int firstColor = Color.parseColor("#0a856f");
    private Bitmap bitmap;
    private Bitmap leftBitmap;
    private Bitmap rightBitmap;

    //bitmap 状态值
    public static final int BITMAP_LEFT = 0;
    public static final int BITMAP_MID = 1;
    public static final int BITMAP_RIGHT = 2;

    private int position = BITMAP_MID;


    public void setFirstColor(int firstColor) {
        this.firstColor = firstColor;
        firstLinePaint.setColor(firstColor);
    }


    public SingleLineContainerView(Context context) {
        this(context, null);
    }

    public SingleLineContainerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public void setPosition(int position) {
        this.position = position;
    }

    public SingleLineContainerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setWillNotDraw(false);

        this.mContext = context;
        //画笔
        firstLinePaint = new Paint();
        firstLinePaint.setAntiAlias(true);
        firstLinePaint.setStrokeWidth(3);
        firstLinePaint.setColor(firstColor);
        firstLinePaint.setStyle(Paint.Style.FILL_AND_STROKE);


        textPaint = new Paint();
        textPaint.setStrokeWidth(3);
        textPaint.setTextSize(getTextSize());
        textPaint.setColor(Color.parseColor("#ff41c496"));
        textPaint.setTextAlign(Paint.Align.LEFT);
        textPaint.setStyle(Paint.Style.FILL);


        bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_qipao);
        leftBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_qipao_left);
        rightBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_qipao_right);

    }

    public double getItemWidth() {
        return itemWidth;
    }

    public void setItemWidth(double itemWidth) {
        this.itemWidth = itemWidth;
    }

    public ArrayList<PointBean> getFirstPoints() {
        return firstPoints;
    }

    public void setFirstPoints(ArrayList<PointBean> firstPoints) {
        this.firstPoints = firstPoints;
        invalidate();
    }

    public PointBean getMaxPoint() {
        return maxPoint;
    }

    public void setMaxPoint(PointBean maxPoint) {
        this.maxPoint = maxPoint;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int height = getMeasuredHeight();

        double dy = (height * 1.000) / 100;

        if (firstPoints != null) {
            float firstPts[] = new float[(firstPoints.size() - 1) * 4];

            if (firstPoints.size() > 1) {

                for (int i = 0; i < firstPoints.size() - 1; i++) {
                    firstPts[4 * i] = (float) (firstPoints.get(i).getPercentX() * itemWidth);
                    firstPts[4 * i + 1] = (float) ((100 - firstPoints.get(i).getPercentY()) * dy);
                    firstPts[4 * i + 2] = (float) (firstPoints.get(i + 1).getPercentX() * itemWidth);
                    firstPts[4 * i + 3] = (float) ((100 - firstPoints.get(i + 1).getPercentY()) * dy);
                }

                canvas.drawLines(firstPts, firstLinePaint);
            }
        }

//        maxPoint = firstPoints.get(6);
//        maxPoint.setNumY(60);
//        position = 2;
        if (maxPoint != null) {
            float left = (float) (maxPoint.getPercentX() * itemWidth);

            if (position == BITMAP_MID) {
                float hight = (float) ((100 - maxPoint.getPercentY()) * dy) - 5;
                int bmpWidth = bitmap.getWidth();
                int bmpHeight = bitmap.getHeight();

                canvas.drawBitmap(bitmap, left - bmpWidth / 2, hight - bmpHeight, firstLinePaint);
                Rect bounds = new Rect();
                textPaint.getTextBounds(str, 0, str.length(), bounds);
                canvas.drawText(maxPoint.getNumY()+"", left - bounds.width() / 2, hight - bmpHeight / 2 + 2, textPaint);
            } else if (position == BITMAP_LEFT) {
                float hight = (float) ((100 - maxPoint.getPercentY()) * dy);
                int bmpWidth = leftBitmap.getWidth();
                int bmpHeight = leftBitmap.getHeight();

                canvas.drawBitmap(leftBitmap, left, hight - bmpHeight, firstLinePaint);
                Rect bounds = new Rect();
                textPaint.getTextBounds(str, 0, str.length(), bounds);
                canvas.drawText(maxPoint.getNumY()+"", left - bounds.width() / 2 + bmpWidth / 2, hight - bmpHeight / 2 + 2, textPaint);
            } else {
                float hight = (float) ((100 - maxPoint.getPercentY()) * dy);
                int bmpWidth = rightBitmap.getWidth();
                int bmpHeight = rightBitmap.getHeight();

                canvas.drawBitmap(rightBitmap, left - bmpWidth, hight - bmpHeight, firstLinePaint);
                Rect bounds = new Rect();
                textPaint.getTextBounds(str, 0, str.length(), bounds);
                canvas.drawText(maxPoint.getNumY()+"", left - bounds.width() / 2 - bmpWidth / 2, hight - bmpHeight / 2 + 2, textPaint);
            }

        }

    }
}
 
 
package com.stategrid.echarge.wedgit.chart;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.stategrid.echarge.R;

import java.util.ArrayList;

/**
 * 底部刻度adpater
 */
public class SingleLineUnitAdapter extends RecyclerView.Adapter<SingleLineUnitAdapter.MyViewHolder> {

    private Context mContext;
    private ArrayList<String> arrayList;
    private double itemWidth;

    public SingleLineUnitAdapter(Context mContext, ArrayList<String> arrayList, double itemWidth) {
        this.mContext = mContext;
        this.arrayList = arrayList;
        this.itemWidth = itemWidth;
    }

    public void setItemWidth(double itemWidth) {
        this.itemWidth = itemWidth;
    }

    public void setArrayList(ArrayList<String> arrayList) {
        this.arrayList = arrayList;
        notifyDataSetChanged();
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_single_unit_layout, parent, false);
        view.findViewById(R.id.tv_unit).getLayoutParams().width = (int) itemWidth;
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.textView.setText(arrayList.get(position));
    }

    @Override
    public int getItemCount() {
        return arrayList == null ? 0 : arrayList.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        private TextView textView;

        public MyViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.tv_unit);
        }
    }
}
 
 
package com.stategrid.echarge.wedgit.chart;

public class PointBean {
    private double percentX;
    private double percentY;

    private int numX;
    private int numY;


    public PointBean() {

    }

    public PointBean(double percentX, double percentY) {
        this.percentX = percentX;
        this.percentY = percentY;
    }

    public PointBean(double percentX, double percentY, int numY) {
        this.percentX = percentX;
        this.percentY = percentY;
        this.numY = numY;
    }

    public PointBean(double percentX, double percentY, int numX, int numY) {
        this.percentX = percentX;
        this.percentY = percentY;
        this.numX = numX;
        this.numY = numY;
    }

    public double getPercentX() {
        return percentX;
    }

    public void setPercentX(double percentX) {
        this.percentX = percentX;
    }

    public double getPercentY() {
        return percentY;
    }

    public void setPercentY(double percentY) {
        this.percentY = percentY;
    }

    public int getNumY() {
        return numY;
    }

    public void setNumY(int numY) {
        this.numY = numY;
    }

    public int getNumX() {
        return numX;
    }

    public void setNumX(int numX) {
        this.numX = numX;
    }
}


猜你喜欢

转载自blog.csdn.net/qq_41238313/article/details/80313105