画天气预报 折线图 源代码

package com.app.map.widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.widget.HorizontalScrollView;

import com.app.map.R;
import com.app.map.model.bean.PointBean;
import com.app.map.model.bean.WeatherBean;

import java.util.ArrayList;
import java.util.List;


public class weatherView extends HorizontalScrollView {

    private Context context;
    private Paint mPaint;
    private Rect mBound;
    private int itemWeight;
    private int itemSize = 0;
    private int width;
    private int height;
    private List<String> str;
    private List<Integer> tempOne;
    private List<Integer> tempTwo;
    private int tempMax = 0;
    private int tempMin = 0;
    private List<String> riqiStr;
    private List<String> weatherStrOne;
    private List<Bitmap> weatherImgOme;
    private List<Bitmap> weatherImgTwo;
    private List<String> weatherStrTwo;
    private List<String> windStr;
    private List<String> windLeverStr;
    private List<String> airQualityColor;
    private List<String> airQuality;
    private Canvas mCanvas;
    private static final int DRAW_ONE_PIC = 1001;
    private static final int DRAW_TWO_PIC = 1002;

    public weatherView(Context context) {
        super(context);
        this.context = context;
        initData();
    }

    public weatherView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        initData();
    }

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

    private void initData() {
        mPaint = new Paint();
        mPaint.setTextSize(dip2px(context, 10));

        mBound = new Rect();

        itemWeight = dip2px(context, 55);//每一个的宽度
    }

    /**
     * 设置数据
     */
    public void setShowData(WeatherBean weatherBean) {
        itemSize = weatherBean.getWeekStr().size();//总共个数
        tempMax = weatherBean.getMaxTemp();//最大值
        tempMin = weatherBean.getMinTemp();//最小值
        str = weatherBean.getWeekStr();//星期
        riqiStr = weatherBean.getRiqiStr();//日期
        weatherStrOne = weatherBean.getWeatherStrOne();//天气
        weatherImgOme = weatherBean.getWeatherImgOme();//天气图片
        tempOne = weatherBean.getTempOne();//第一条温度数据
        tempTwo = weatherBean.getTempTwo();//第二条温度数据
        weatherImgTwo = weatherBean.getWeatherImgTwo();//天气图片
        weatherStrTwo = weatherBean.getWeatherStrTwo();//天气
        windStr = weatherBean.getWindStr();//风的类型
        windLeverStr = weatherBean.getWindLeverStr();//风的级别
        airQualityColor = weatherBean.getAirQualityColor();//质量背景色
        airQuality = weatherBean.getAirQuality();//质量
        invalidate();
    }

    @Override
    protected void onDraw(final Canvas canvas) {
        mCanvas = canvas;
        super.onDraw(canvas);
        width = getWidth();
        height = getHeight();
        //设置背景色
        setBackgroundColor(Color.parseColor("#88253643"));

        //画分割线
        mPaint.setColor(getResources().getColor(R.color.transparent_white_55));
        mPaint.setStrokeWidth(dip2px(context, 0.5f));
        canvas.drawLine(0, dip2px(context, 10), width, dip2px(context, 10), mPaint);

        //画虚线
        mPaint.setAntiAlias(true);
        mPaint.setPathEffect(new DashPathEffect(new float[]{4, 4}, 0));
        mPaint.setStyle(Paint.Style.STROKE);
        for (int i = 0; i < itemSize; i++) {
            Path path = new Path();
            path.moveTo(itemWeight * (i + 1), dip2px(context, 10));
            path.lineTo(itemWeight * (i + 1), dip2px(context, 450));
            canvas.drawPath(path, mPaint);
        }

        //画星期
        mPaint.setTextSize(dip2px(context, 13));
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.WHITE);
        mPaint.getTextBounds(str.get(0), 0, str.get(0).length(), mBound);
        float strWidth = mBound.width();
        for (int i = 0; i < itemSize; i++) {
            canvas.drawText(str.get(i), itemWeight / 2 + i * itemWeight - strWidth / 2, dip2px(context, 28), mPaint);
        }

        //画日历
        mPaint.setTextSize(dip2px(context, 12));
        mPaint.getTextBounds(riqiStr.get(0), 0, riqiStr.get(0).length(), mBound);
        float strRiQiWidth = mBound.width();
        for (int i = 0; i < itemSize; i++) {
            canvas.drawText(riqiStr.get(i), itemWeight / 2 + i * itemWeight - strRiQiWidth / 2, dip2px(context, 42), mPaint);
        }

        //画天气
        mPaint.setTextSize(dip2px(context, 13));
        for (int i = 0; i < itemSize; i++) {
            mPaint.getTextBounds(weatherStrOne.get(i), 0, weatherStrOne.get(i).length(), mBound);
            float strSkyWidth = mBound.width();
            canvas.drawText(weatherStrOne.get(i), itemWeight / 2 + i * itemWeight - strSkyWidth / 2, dip2px(context, 64), mPaint);
        }

        //画天气图片

        for (int i = 0; i < weatherImgOme.size(); i++) {
            canvas.drawBitmap(weatherImgOme.get(i), itemWeight / 2 + i * itemWeight - weatherImgOme.get(i).getWidth() / 2, dip2px(context, 75), mPaint);
        }
        //   Bitmap mBitmap = ((BitmapDrawable) ContextCompat.getDrawable(context, )).getBitmap();
       /* new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < itemSize; i++) {
                    mBitmap[0] = UrlToDrawableUtil.getBitMBitmap(weatherImgOme.get(i));
                    DrawPicInfo drawPicInfo = new DrawPicInfo();
                    drawPicInfo.setBitmap(mBitmap[0]);
                    drawPicInfo.setIndex(i);
                    Message message = handler.obtainMessage();
                    message.obj = drawPicInfo;
                    message.what = DRAW_ONE_PIC;
                    handler.sendMessage(message);
                    drawPicInfo = null;
                    message = null;
                    mBitmap[0].recycle();
                }
            }
        }).start();*/


        //分割区域---折线图
        /**
         * 头部
         */
        /*mPaint.setColor(Color.RED);
        canvas.drawLine(0, dip2px(context, 125), width, dip2px(context, 125), mPaint);//145*/

        /**
         * 曲线第一部分
         */
        int diffValue = tempMax - tempMin;
        float tempHeight = dip2px(context, 125) / diffValue;//每度的高度
        mPaint.setColor(Color.WHITE);
        List<PointBean> pointOneList = new ArrayList<>();
        for (int i = 0; i < itemSize; i++) {
            float tempIndexCountHeight = 0;
            if (tempOne.get(i) < tempMax && tempOne.get(i) > tempMin) {//两者之间,不包含
                tempIndexCountHeight = dip2px(context, 260) - (tempOne.get(i) - tempMin) * tempHeight;
            }
            if (tempOne.get(i) == tempMax) {//等于最大
                tempIndexCountHeight = dip2px(context, 125);
            }
            if (tempOne.get(i) == tempMin) {//等于最小
                tempIndexCountHeight = dip2px(context, 260);
            }
            float dianX = itemWeight / 2 + itemWeight * i;
            float dianY = tempIndexCountHeight;
            pointOneList.add(new PointBean(dianX, dianY));
        }
        //划线
        mPaint.setColor(Color.parseColor("#D5B82F"));
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaint.setStrokeWidth(3);
        for (int i = 0; i < pointOneList.size(); i++) {
            if (i + 1 < pointOneList.size()) {
                Path bezierPath = new Path();
                bezierPath.moveTo(pointOneList.get(i).getDianX(), pointOneList.get(i).getDianY());
                bezierPath.cubicTo((i + 1) * itemWeight, pointOneList.get(i).getDianY(),
                        (i + 1) * itemWeight, pointOneList.get(i + 1).getDianY(),
                        pointOneList.get(i + 1).getDianX(), pointOneList.get(i + 1).getDianY());
                canvas.drawPath(bezierPath, mPaint);
            }
        }
        //画点
        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.FILL);
        for (int i = 0; i < pointOneList.size(); i++) {
            canvas.drawCircle(pointOneList.get(i).getDianX(), pointOneList.get(i).getDianY(), dip2px(context, 2), mPaint);
        }
        //画温度数
        for (int i = 0; i < tempOne.size(); i++) {
            mPaint.getTextBounds(tempOne.get(i) + "°", 0, (tempOne.get(i) + "°").length(), mBound);
            float ziTiWidth = mBound.width();
            canvas.drawText(tempOne.get(i) + "°", pointOneList.get(i).getDianX() - ziTiWidth / 2, pointOneList.get(i).getDianY() - dip2px(context, 8), mPaint);
        }

        //曲线第二部分
        mPaint.setColor(Color.WHITE);
        List<PointBean> pointTwoList = new ArrayList<>();
        for (int i = 0; i < itemSize; i++) {
            float tempIndexCountHeight = 0;
            if (tempTwo.get(i) < tempMax && tempTwo.get(i) > tempMin) {//两者之间,不包含
                tempIndexCountHeight = dip2px(context, 260) - (tempTwo.get(i) - tempMin) * tempHeight;
            }
            if (tempTwo.get(i) == tempMax) {//等于最大
                tempIndexCountHeight = dip2px(context, 125);
            }
            if (tempTwo.get(i) == tempMin) {//等于最小
                tempIndexCountHeight = dip2px(context, 260);
            }
            float dianX = itemWeight / 2 + itemWeight * i;
            float dianY = tempIndexCountHeight;
            pointTwoList.add(new PointBean(dianX, dianY));
        }
        //划线
        mPaint.setColor(Color.parseColor("#83C6D4"));
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaint.setStrokeWidth(3);
        for (int i = 0; i < pointTwoList.size(); i++) {
            if (i + 1 < pointTwoList.size()) {
                Path bezierPath = new Path();
                bezierPath.moveTo(pointTwoList.get(i).getDianX(), pointTwoList.get(i).getDianY());
                bezierPath.cubicTo((i + 1) * itemWeight, pointTwoList.get(i).getDianY(),
                        (i + 1) * itemWeight, pointTwoList.get(i + 1).getDianY(),
                        pointTwoList.get(i + 1).getDianX(), pointTwoList.get(i + 1).getDianY());
                canvas.drawPath(bezierPath, mPaint);
            }
        }
        //画点
        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.FILL);
        for (int i = 0; i < pointTwoList.size(); i++) {
            canvas.drawCircle(pointTwoList.get(i).getDianX(), pointTwoList.get(i).getDianY(), dip2px(context, 2), mPaint);
        }
        //画温度数
        for (int i = 0; i < tempTwo.size(); i++) {
            mPaint.getTextBounds(tempTwo.get(i) + "°", 0, (tempTwo.get(i) + "°").length(), mBound);
            float ziTiWidth = mBound.width();
            canvas.drawText(tempTwo.get(i) + "°", pointTwoList.get(i).getDianX() - ziTiWidth / 2, pointTwoList.get(i).getDianY() + dip2px(context, 16), mPaint);
        }

        /**
         * 底部
         */
        /*mPaint.setColor(Color.RED);
        canvas.drawLine(0, dip2px(context, 270), width, dip2px(context, 270), mPaint);*/

        //画天气图片

        for (int i = 0; i < weatherImgTwo.size(); i++) {
            canvas.drawBitmap(weatherImgTwo.get(i), itemWeight / 2 + i * itemWeight - weatherImgTwo.get(i).getWidth() / 2, dip2px(context, 285), mPaint);
        }
      /*  post(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < itemSize; i++) {

//            Bitmap mBitmap = ((BitmapDrawable) ContextCompat.getDrawable(context, weatherImgTwo.get(i))).getBitmap();
                    Bitmap mBitmap = UrlToDrawableUtil.getBitMBitmap(weatherImgTwo.get(i));
                    canvas.drawBitmap(mBitmap, itemWeight / 2 + i * itemWeight - mBitmap.getWidth() / 2, dip2px(context, 295), mPaint);
                }
            }
        });*/

        /*new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < itemSize; i++) {
                    mBitmap[0] = getBitMBitmap(weatherImgTwo.get(i));
                    DrawPicInfo drawPicInfo = new DrawPicInfo();
                    drawPicInfo.setBitmap(mBitmap[0]);
                    drawPicInfo.setIndex(i);
                    Message message = handler.obtainMessage();
                    message.obj = drawPicInfo;
                    message.what = DRAW_TWO_PIC;
                    handler.sendMessage(message);
                    drawPicInfo = null;
                    message = null;
                    mBitmap[0].recycle();

                }
            }
        }).start();*/


        //画天气
        mPaint.setColor(Color.WHITE);
        mPaint.setTextSize(dip2px(context, 13));
        for (int i = 0; i < itemSize; i++) {
            mPaint.getTextBounds(weatherStrTwo.get(i), 0, weatherStrTwo.get(i).length(), mBound);
            float strSkyWidthTwo = mBound.width();
            canvas.drawText(weatherStrTwo.get(i), itemWeight / 2 + i * itemWeight - strSkyWidthTwo / 2, dip2px(context, 340), mPaint);//9
        }

        //画风
        mPaint.setTextSize(dip2px(context, 11));
        for (int i = 0; i < itemSize; i++) {
            mPaint.getTextBounds(windStr.get(i), 0, windStr.get(i).length(), mBound);
            float strWindWidth = mBound.width();
            canvas.drawText(windStr.get(i), itemWeight / 2 + i * itemWeight - strWindWidth / 2, dip2px(context, 360), mPaint);//20
        }

        //画风级别
        mPaint.getTextBounds(windLeverStr.get(0), 0, windLeverStr.get(0).length(), mBound);
        float strJiBieWidth = mBound.width();
        for (int i = 0; i < itemSize; i++) {
            canvas.drawText(windLeverStr.get(i), itemWeight / 2 + i * itemWeight - strJiBieWidth / 2, dip2px(context, 375), mPaint);//15
        }

        //差、良、优(背景)
        float radius = dip2px(context, 3.5f);
        float rectFWidth = dip2px(context, 25);
        float rectFHeight = dip2px(context, 14f);
        float cneterY = dip2px(context, 390);//15
        for (int i = 0; i < itemSize; i++) {
            mPaint.setColor(Color.parseColor(airQualityColor.get(i)));
            float centerX = itemWeight / 2 + i * itemWeight;
            RectF rectF = new RectF();
            rectF.left = centerX - rectFWidth / 2;
            rectF.right = centerX + rectFWidth / 2;
            rectF.top = cneterY - rectFHeight / 2;
            rectF.bottom = cneterY + rectFHeight / 2;
            canvas.drawRoundRect(rectF, radius, radius, mPaint);
        }

        //差、良、优
        mPaint.setColor(Color.WHITE);
        mPaint.setTextSize(dip2px(context, 10));
        mPaint.getTextBounds(airQuality.get(0), 0, airQuality.get(0).length(), mBound);
        float youWidth = mBound.width();
        float youHeiht = mBound.height();
        for (int i = 0; i < itemSize; i++) {
            canvas.drawText(airQuality.get(i), itemWeight / 2 - youWidth / 2 + i * itemWeight, cneterY + youHeiht * 0.35f, mPaint);
        }

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(itemWeight * itemSize, dip2px(context, 450));
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    private int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    public void setWeatherIcon(List<Bitmap> bitmapList,int tag){
       if (bitmapList!=null&&bitmapList.size()>0){
           if (tag==0){
               weatherImgOme =bitmapList;
           }
           else {
               weatherImgTwo = bitmapList;
           }
       }
       postInvalidate();
    }

    final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            int what = msg.what;
            DrawPicInfo drawPicInfo = (DrawPicInfo) msg.obj;
            switch (what) {
                case DRAW_ONE_PIC:
                    mCanvas.drawBitmap(drawPicInfo.getBitmap(), itemWeight / 2 + drawPicInfo.getIndex() * itemWeight - drawPicInfo.getBitmap().getWidth() / 2, dip2px(context, 75), mPaint);
                    break;
                case DRAW_TWO_PIC:
                    mCanvas.drawBitmap(drawPicInfo.getBitmap(), itemWeight / 2 + drawPicInfo.getIndex() * itemWeight - drawPicInfo.getBitmap().getWidth() / 2, dip2px(context, 295), mPaint);
                    break;
            }
            drawPicInfo.recycle();
        }

    };

    private static class DrawPicInfo {
        private Bitmap mBitmap;
        private int index;

        public void recycle() {
            if (mBitmap != null) {
                mBitmap.recycle();
            }
        }

        public Bitmap getBitmap() {
            return mBitmap;
        }

        public void setBitmap(Bitmap bitmap) {
            mBitmap = bitmap;
        }

        public int getIndex() {
            return index;
        }

        public void setIndex(int index) {
            this.index = index;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/wolfking0608/article/details/81198934
今日推荐