美文网首页
一个简单的天气图表

一个简单的天气图表

作者: 留给时光吧 | 来源:发表于2018-05-08 20:53 被阅读0次

    先看一下效果,完整代码


    首先我们定义几个变量用来存放数据

        private static final int DAY_NUM = 6; //天数,实际应用可以根据数据调整
        private int[] temMax = new int[DAY_NUM];//最高温度的集合
        private int[] temMin = new int[DAY_NUM];//最低温度的集合
        private Bitmap[] weatherIcon = new Bitmap[DAY_NUM];//天气图片集合
        private String[] time = new String[DAY_NUM];//时间集合
    

    我们这个图标主要分5部分:每天之间的分割线,最高温度曲线,最低温度曲线,天气图标,日期。只要一步一步实现即可

    1 分割线

    这个很简单,平分之后划线即可,注意每条线坐标的计算

        private void drawDayDivide(Canvas canvas,int flag) {
            for(int i = 1 ; i < flag ; i++){
                canvas.drawLine(i * dayWidth, DIVIDE_MARGIN, i * dayWidth, mHeight - DIVIDE_MARGIN, mDayDividePaint);
            }
        }
    

    2. 最高最低温度曲线

    我们将整个图标的高度分为三部分,最高温度曲线和最低温度曲线分别占用前两块区域。划线的第一步是描点,先得到一组温度中的最大最小值,确定线的高低点,然后中间的数据依比例画出对应点,最后连线:

    数据的计算:

            maxInMax = getMax(temMax);
            minInMax = getMin(temMax);
    
            maxInMin = getMax(temMin);
            minInMin = getMin(temMin);
    
            diffInMax = maxInMax - minInMax;
            diffInMin = maxInMin - minInMin;
    
            diffInMaxHeight = diffInMax == 0 ? 0: (partHeight- PART_MARGIN *2) / diffInMax;
            diffInMinHeight = diffInMin == 0 ? 0: (partHeight- PART_MARGIN *2) / diffInMin;
    
        private int getMin(int[] m) {
            int tmp = m[0];
            for (int i : m) {
                tmp = tmp < i ? tmp : i;
            }
            return tmp;
        }
    
        private int getMax(int[] m) {
            int tmp = m[0];
            for (int i : m) {
                tmp = tmp > i ? tmp : i;
            }
            return tmp;
        }
    

    绘图:

       private void drawPointAndTemperatureLine(Canvas canvas,int flag) {
            int x,y;
            Path maxPath = new Path();
            Path minPath = new Path();
            String temp ;
            //循环画出所有点
            for(int i = 0 ; i < flag ; i++){
                //第一个点的横坐标
                x = firstPointX + dayWidth * i;
                
                //计算纵坐标,如果所有数据都一样,则画到对应区域中央,否则根据比例定点
                if(diffInMax == 0){
                    y = partHeight / 2;
                }else{
                    y = Math.abs(temMax[i] - maxInMax) * diffInMaxHeight + PART_MARGIN;
                }
    
                //画点
                canvas.drawCircle(x , y , POINT_RADIUS , mPointPaint);
                temp = temMax[i]+DEGREE;
    
                //画出温度文字,要在点的上方居中
                canvas.drawText(temp , x - mTextPaint.measureText(temp)/2 , y - TEXT_MARGIN , mTextPaint);
    
                //对path操作
                if(i == 0){
                    maxPath.moveTo(x , y);
                }else{
                    maxPath.lineTo(x , y);
                }
    
                //绘制最低温度的点,逻辑和上面一样
                if(diffInMin == 0){
                    y = partHeight / 2 + partHeight;
                }else{
                    y = Math.abs(temMin[i] - maxInMin) * diffInMinHeight + PART_MARGIN + partHeight;
                }
                canvas.drawCircle(x , y , POINT_RADIUS , mPointPaint);
                temp = temMin[i]+DEGREE;
                canvas.drawText(temp , x - mTextPaint.measureText(temp)/2 , y - TEXT_MARGIN , mTextPaint);
                if(i == 0){
                    minPath.moveTo(x , y);
                }else{
                    minPath.lineTo(x , y);
                }
            }
    
            //连线
            canvas.drawPath(maxPath , mMaxLinePaint);
            canvas.drawPath(minPath , mMinLintPaint);
        }
    
    

    3.天气图片及文字

    我们之前将整个高度划分为三部分,图片及文字占最后一部分:

        private void drawWeatherIconAndText(Canvas canvas,int flag) {
            Bitmap icon = null;
            for (int i = 0 ; i < flag ; i++){
                if(weatherIcon[i]==null){
                    continue;
                }
                float r = (partHeight - partHeight * 3 / 9 - mTextPaint.descent() + mTextPaint.ascent() ) / weatherIcon[i].getHeight();
                icon = scaleBitmap(weatherIcon[i],r);
                canvas.drawBitmap(icon, dayWidth / 2 - icon.getWidth() / 2 + dayWidth * i, partHeight * 2 , null);
                canvas.drawText(time[i], dayWidth / 2 - mTextPaint.measureText(time[i]) / 2 + dayWidth * i, partHeight * 2 + icon.getHeight() + partHeight * 2 / 9, mTextPaint);
    
            }
        }
    
        private Bitmap scaleBitmap(Bitmap origin, float ratio) {
            if (origin == null) {
                return null;
            }
            int width = origin.getWidth();
            int height = origin.getHeight();
            Matrix matrix = new Matrix();
            matrix.preScale(ratio, ratio);
            Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
            if (newBM.equals(origin)) {
                return newBM;
            }
            return newBM;
        }
    

    首先要对图片进行一次缩放,由于图片要主要显示,所以去掉上下边距及文字的高度,剩下的都给图片来显示。文字的绘制也没什么难点,主要是居中即可。

    4. 动画

    我们这里简单实现一个从左到右依次出现的动画。这里转换一下逻辑,正常绘制时每块需要循环DAY_NUM 次,开启动画时我们将要绘制的天数递增,每增加一次,就绘制一次,这样就有动画效果了:

        public void startAnimation(){
            animFlag = 0;
            handler.sendEmptyMessage(0);
        }
    
        public void cleanAnimation(){
            handler.removeMessages(0);
            animFlag = 0;
            postInvalidate();
        }
    
        private android.os.Handler handler = new android.os.Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (animFlag < DAY_NUM){
                    postInvalidate();
                    animFlag++;
                    sendEmptyMessageDelayed(0,50);
                }
            }
        };
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawColor(getResources().getColor(R.color.colorTransparent));
            computer();
            drawDayDivide(canvas,animFlag);
            drawPointAndTemperatureLine(canvas,animFlag);
            drawWeatherIconAndText(canvas,animFlag);
        }
    

    相关文章

      网友评论

          本文标题:一个简单的天气图表

          本文链接:https://www.haomeiwen.com/subject/cnswrftx.html