广告
返回顶部
首页 > 资讯 > 移动开发 >Android自定义View实现天气预报折线图
  • 865
分享到

Android自定义View实现天气预报折线图

2024-04-02 19:04:59 865人浏览 独家记忆
摘要

本文实例为大家分享了Android自定义View画天气预报折线图的具体代码,供大家参考,具体内容如下 效果图如下: 刚开始尝试用第三方画曲线的框架来画效果图,后来发现曲线间的阴影当

本文实例为大家分享了Android自定义View画天气预报折线图的具体代码,供大家参考,具体内容如下

效果图如下:

刚开始尝试用第三方画曲线的框架来画效果图,后来发现曲线间的阴影当有负数的度数的时候画不出来,而且不需要点击放大、点点可点的效果,用框架显得很臃肿,所以最后用自定义View来画的折线图。自定义画折线图的大致思路:这个图是有多个四边形组成的(4个点连接起来就是一个四边形),两边延伸:添加四个多余的点,将左右的边距设置成负数即可。

代码如下:

public class WeatherChartView extends View {

    
    private float mXAxis[] ;

    
    private float mYAxisDay[] ;

    
    private float mYAxisNight[] ;

    
    private int LENGTH ;

    
    private int mTempDay[] ;

    
    private int mTempNight[] ;

    
    private int mHeight;

    
    private float mTextSize;

    
    private float mRadius ;

    
    private float mRadiusToday ;

    
    private float mTextSpace ;

    
    private float mStokeWidth ;

    
    private int mColorDay = Color.parseColor("#ffffff");

    
    private int mColorNight = Color.parseColor("#ffffff");;

    
    private int mTextColor = Color.parseColor("#ffffff");;

    
    private float mDensity;

    
    private float mSpace;

    @SuppressWarnings("deprecation")
    public WeatherChartView(Context context, AttributeSet attrs) {
        super(context, attrs); 
        mDensity = getResources().getDisplayMetrics().density;
        mRadius = 3 * mDensity;
        mRadiusToday = 3 * mDensity;
        //mSpace = 3 * mDensity;
        mTextSpace = 10 * mDensity;
        mStokeWidth = 2 * mDensity;
        mTextSize = BreakRuleTools.dip2px(context, 12);
    }

    public WeatherChartView(Context context) {
        super(context);
    }

    @Override
    protected void onDraw(canvas canvas) {
        super.onDraw(canvas);
        if (mHeight == 0) {
            // 设置控件高度,x轴集合
            setHeightAndXAxis();
        }
        // 计算y轴集合数值
        computeYAxisValues();
        // 画白天折线图
        drawChart(canvas, mColorDay, mTempDay, mYAxisDay, 0);
        // 画夜间折线图
        drawChart(canvas, mColorNight, mTempNight, mYAxisNight, 1);
    }

    
    private void computeYAxisValues() {
        // 存放白天最低温度
        int minTempDay = mTempDay[0];
        // 存放白天最高温度
        int maxTempDay = mTempDay[0];
        for (int item : mTempDay) {
            if (item < minTempDay) {
                minTempDay = item;
            }
            if (item > maxTempDay) {
                maxTempDay = item;
            }
        }

        // 存放夜间最低温度
        int minTempNight = mTempNight[0];
        // 存放夜间最高温度
        int maxTempNight = mTempNight[0];
        for (int item : mTempNight) {
            if (item < minTempNight) {
                minTempNight = item;
            }
            if (item > maxTempNight) {
                maxTempNight = item;
            }
        }

        // 白天,夜间中的最低温度
        int minTemp = minTempNight < minTempDay ? minTempNight : minTempDay;
        // 白天,夜间中的最高温度
        int maxTemp = maxTempDay > maxTempNight ? maxTempDay : maxTempNight;

        // 份数(白天,夜间综合温差)
        float parts = maxTemp - minTemp;
        // y轴一端到控件一端的距离
        float length = mSpace + mTextSize + mTextSpace + mRadius;
        // y轴高度
        float yAxisHeight = mHeight - length * 2;

        // 当温度都相同时(被除数不能为0)
        if (parts == 0) {
            for (int i = 0; i < LENGTH; i++) {
                mYAxisDay[i] = yAxisHeight / 2 + length;
                mYAxisNight[i] = yAxisHeight / 2 + length;
            }
        } else {
            float partValue = yAxisHeight / parts;
            for (int i = 0; i < LENGTH; i++) {
                mYAxisDay[i] = mHeight - partValue * (mTempDay[i] - minTemp) - length;
                mYAxisNight[i] = mHeight - partValue * (mTempNight[i] - minTemp) - length;
            }
        }
    }

    
    private void drawChart(Canvas canvas, int color, int temp[], float[] yAxis, int type) {
        color = Color.parseColor("#ffffff");
        // 线画笔
        Paint linePaint = new Paint();
        // 抗锯齿
        linePaint.setAntiAlias(true);
        // 线宽
        linePaint.setStrokeWidth(mStokeWidth);
        linePaint.setColor(color);
        // 空心
        linePaint.setStyle(Paint.Style.STROKE);

        // 点画笔
        Paint pointPaint = new Paint();
        pointPaint.setAntiAlias(true);
        pointPaint.setColor(color);

        // 字体画笔
        Paint textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setColor(mTextColor);
        textPaint.setTextSize(mTextSize);
        // 文字居中
        textPaint.setTextAlign(Paint.Align.CENTER);

        int alpha1 = 102;
        int alpha2 = 255;
        for (int i = 0; i < LENGTH; i++) {
            // 画线
            if (i < LENGTH - 1) {
                // 昨天
                if (i == -1) {
                    linePaint.setAlpha(alpha1);
                    // 设置虚线效果
                    linePaint.setPathEffect(new DashPathEffect(new float[]{2 * mDensity, 2 * mDensity}, 0));
                    // 路径
                    Path path = new Path();
                    // 路径起点
                    path.moveTo(mXAxis[i], yAxis[i]);
                    // 路径连接到
                    path.lineTo(mXAxis[i + 1], yAxis[i + 1]);
                    canvas.drawPath(path, linePaint);
                } else {
                    if(type == 0) {
                        linePaint.setAlpha(76);
                        linePaint.setPathEffect(null);

                        linePaint.setStyle(Paint.Style.FILL);//设置实心
                        Path path = new Path();                     //Path对象
                        path.moveTo(mXAxis[i], mYAxisDay[i]);                           //起始点
                        path.lineTo(mXAxis[i + 1], mYAxisDay[i + 1]);                           //连线到下一点
                        path.lineTo(mXAxis[i + 1], mYAxisNight[i + 1]);                      //连线到下一点
                        path.lineTo(mXAxis[i], mYAxisNight[i]);                      //连线到下一点
                        path.lineTo(mXAxis[i], mYAxisDay[i]);                      //连线到下一点
                        canvas.drawPath(path, linePaint);                   //绘制任意多边形
                    }
                    //canvas.drawLine(mXAxis[i], yAxis[i], mXAxis[i + 1], yAxis[i + 1], linePaint);
                }
            }

            // 画点
            if (i != 1) {
                // 昨天
                if (i == 0 || i == LENGTH - 1) {
                    
                } else {
                    pointPaint.setAlpha(alpha2);
                    canvas.drawCircle(mXAxis[i], yAxis[i], mRadius, pointPaint);
                }
                // 今天
            } else {
                pointPaint.setAlpha(alpha2);
                canvas.drawCircle(mXAxis[i], yAxis[i], mRadiusToday, pointPaint);
            }

            // 画字
            // 昨天
            if (i == 0 || i == LENGTH - 1) {
                
            } else {
                textPaint.setAlpha(alpha2);
                drawText(canvas, textPaint, i, temp, yAxis, type);
            }
        }
    }

    
    private void drawText(Canvas canvas, Paint textPaint, int i, int[] temp, float[] yAxis, int type) {
        switch (type) {
            case 0:
                // 显示白天气温
                canvas.drawText(temp[i] + "°", mXAxis[i], yAxis[i] - mRadius - mTextSpace, textPaint);
                break;
            case 1:
                // 显示夜间气温
                canvas.drawText(temp[i] + "°", mXAxis[i], yAxis[i] + mTextSpace + mTextSize, textPaint);
                break;
        }
    }

    
    private void setHeightAndXAxis() {
        mHeight = getHeight();
        // 控件宽
        int width = getWidth();
        int i = LENGTH - 2;
        // 每一份宽
        float w = width / (i*2);

        for(int j =0;j<LENGTH;j++){
            if(j == 0){
                mXAxis[j] = 0;
            } else if(j == LENGTH -1){
                mXAxis[j] = width;
            } else{
                mXAxis[j] = w * (2*j -1);
            }
        }
       
       
    }

    
    public void setTempDay(int[] tempDay) {
        mTempDay = tempDay;
        LENGTH = mTempDay.length;

        mXAxis = new float[LENGTH];
        mYAxisDay = new float[LENGTH];
        mYAxisNight = new float[LENGTH];
        
    }

    
    public void setTempNight(int[] tempNight) {
        mTempNight = tempNight;
    }

    
    public void setColorDay(){}
}

布局代码:

<com.pingan.carowner.weather.view.WeatherChartView
            android:id="@+id/line_char"
            android:layout_width="match_parent"
            android:layout_height="180dp"
            android:layout_below="@id/weather_over_view_item3"
            android:layout_centerInParent="true"/>

代码引用:

// 设置白天温度曲线
mChartView = (WeatherChartView) findViewById(R.id.line_char);
mChartView.setTempDay(highTemp);//highTemp 高温度集合
// 设置夜间温度曲线
mChartView.setTempNight(lowTemp);//lowTemp 低温集合
mChartView.invalidate();

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: Android自定义View实现天气预报折线图

本文链接: https://www.lsjlt.com/news/167352.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android自定义View实现天气预报折线图
    本文实例为大家分享了Android自定义View画天气预报折线图的具体代码,供大家参考,具体内容如下 效果图如下: 刚开始尝试用第三方画曲线的框架来画效果图,后来发现曲线间的阴影当...
    99+
    2022-11-13
  • Android自定义View实现折线图效果
    下面就是结果图(每种状态用一个表情图片表示): 一、主页面的布局文件如下: <RelativeLayout xmlns:android="http://schema...
    99+
    2022-06-06
    折线图 view Android
  • Android自定义View之渐变色折线图的实现
    目录前言如何实现总结前言 在之前的项目中,有做过一个需求,需要实现一个颜色渐变的折线图。当时项目中使用的图表库是MPAndroidChart,但是该库没有提供合适的方法来实现想要的效...
    99+
    2022-11-13
  • Android怎么自定义View实现渐变色折线图
    这篇文章主要介绍“Android怎么自定义View实现渐变色折线图”,在日常操作中,相信很多人在Android怎么自定义View实现渐变色折线图问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android怎么...
    99+
    2023-06-30
  • Android自定义View简易折线图控件(二)
    继续练习自定义View,这次带来的是简易折线图,支持坐标点点击监听,效果如下: 画坐标轴、画刻度、画点、连线。。x、y轴的数据范围是写死的 1 <= x <= 7...
    99+
    2022-06-06
    折线图 view Android
  • Android 实现自定义折线图控件
    目录前言概述原点计算Y轴宽度计算X轴高度X轴绘制轴线X轴刻度间隔网格线、文本Y轴计算Y轴分布刻度间隔、网格线、文本折线代码前言 日前,有一个“折现图”的需求,...
    99+
    2022-11-13
  • Android自定义View实现气泡动画
    本文实例为大家分享了Android自定义View实现气泡动画的具体代码,供大家参考,具体内容如下 一、前言 最近有需求制作一个水壶的气泡动画,首先在网上查找了一番,找到了一个文章:A...
    99+
    2022-11-12
  • Android怎么实现自定义折线图控件
    这篇“Android怎么实现自定义折线图控件”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Android怎么实现自定义折线图...
    99+
    2023-07-02
  • Android 自定义View实现芝麻分曲线图效果
    1.简介 其实这个效果几天之前就写了,但是一直没有更新博客,本来想着把芝麻分雷达图也做好再发博客的,然后今天看到鸿洋的微信公众号有朋友发了芝麻分的雷达图,所以就算了,算是一个互...
    99+
    2022-06-06
    view 自定义view Android
  • Android自定义View实现心形图案
    本文实例为大家分享了Android自定义View实现心形的具体代码,供大家参考,具体内容如下 通过继承View实现的❤形 在绘制心形需要Path类中的两个重要方法分别...
    99+
    2022-11-12
  • Android自定义View实现shape图形绘制
    概述 之前曾写过一篇文章介绍了Android中drawable使用Shape资源,通过定义drawable中的shape资源能够绘制简单的图形效果,如矩形,椭圆形,线形和圆环等...
    99+
    2022-06-06
    shape view Android
  • Android实现自定义曲线图
    一般来说应用中比较常见的是折线图,直方图这种比较多,今天来写一个项目中的需求曲线图,也是在之前的折线图基础上改进而来,看效果图 主要考虑曲线的实现以及阴影部分的实现 先看代码: i...
    99+
    2022-11-13
  • Android自定义View绘图实现拖影动画
    前几天在“Android绘图之渐隐动画”一文中通过画线实现了渐隐动画,但里面有个问题,画笔较粗(大于1)时线段之间会有裂隙,我又改进了一下。这次效果好多了。 先看效果吧: 然...
    99+
    2022-06-06
    view 动画 Android
  • Android自定义View绘图实现渐隐动画
    实现了一个有趣的小东西:使用自定义View绘图,一边画线,画出的线条渐渐变淡,直到消失。效果如下图所示: 用属性动画或者渐变填充(Shader)可以做到一笔一笔的变化,但要想...
    99+
    2022-06-06
    view 动画 Android
  • vue使用高德地图实现实时定位天气预报功能
    目录JSAPI 的加载使用 JSAPI Loader (推荐)JSAPI key和安全密钥的使用项目代码步骤:1、在index.html页面body中添加密钥2、安装@amap/am...
    99+
    2022-11-13
  • Android自定义View实现多图片选择控件
    前言 相信很多朋友在开发中都会遇到图片上传的情况,尤其是多图上传,最经典的莫过于微信的图片选择了。所有很多情况下会使用到多图选择,所以就有了这篇文章,今天抽点时间写了个控件。 ...
    99+
    2022-06-06
    view 选择 图片 Android
  • Android自定义View——扇形统计图的实现代码
    Android 扇形统计图 先看看效果: 看上去如果觉得还行就继续往下看吧! 自定义View 定义成员变量 private int mHeight, mWidth;/...
    99+
    2022-06-06
    扇形统计图 view 统计图 Android
  • 仿墨迹天气在Android App中实现自定义zip皮肤更换
    在这里谈一下墨迹天气的换肤实现方式,不过首先声明我只是通过反编译以及参考了一些网上其他资料的方式推测出的换肤原理, 在这里只供参考. 若大家有更好的方式, 欢迎交流. 墨迹天气...
    99+
    2022-06-06
    天气 zip app Android
  • Android自定义view实现电影票在线选座功能
    先看看电影票在线选座功能实现的效果图: 界面比较粗糙,主要看原理。 这个界面主要包括以下几部分 1、座位 2、左边的排数 3、左上方的缩略图 4、缩略图中的红色...
    99+
    2022-06-06
    电影 view Android
  • Android自定义View绘制贝塞尔曲线实现流程
    目录前言二阶贝塞尔曲线三阶贝塞尔曲线前言 对于Android开发,实现贝塞尔曲线还是比较方便的,有对应的API供你调用。由于一阶贝塞尔曲线就是一条直线,实际没啥多大用处,因此,下面主...
    99+
    2022-11-13
    Android 贝塞尔曲线 Android 贝塞尔曲线实现方法
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作