热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android自定义View柱状统计图

关于自定义View,相信多数开发者都已经非常熟悉了,网络上的例子也非常多,各种炫酷吊炸天的自定义View也层出不穷。本文只是一个初级学习教程,对于初学者有参考价值。下面正式进入主

关于自定义View,相信多数开发者都已经非常熟悉了,网络上的例子也非常多,各种炫酷吊炸天的自定义View也层出不穷。本文只是一个初级学习教程,对于初学者有参考价值。

下面正式进入主题。

本文采用自定义View的方式实现柱状统计图BarGraphView,实现了柱状统计图的基本功能,因为本身是为了学习自定义View,因此扩展性比较差,只能作为自定义View的参考。

上效果图:

技术分享


View显示到屏幕上主要经过这三个过程

(1)Measure(测量)

首先View需要测量自身的大小,包括长和宽。 当View类的成员函数measure决定要重新测量当前View的宽度和高度之后,会去调用另外一个成员函数onMeasure来真正执行测量宽度和高度的操作。因此,自定义View大多都需要覆写onMeasure方法来测量View的大小。onMeasure方法如下:

  @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

其中widthMeasureSpec和heightMeasureSpec两个参数为父视图的建议大小。 参数measureSpec的值其实是由两部分内容来组成的,最高2位表示一个测量模式,而低30位表示一个宽度值或者高度值,测量模式有三种,分别是MeasureSpec.EXACTLY、MeasureSpec.UNSPECIFIED和MeasureSpec.AT_MOST,这里就不讲三种模式的区别了。在BarGraphView中将会参考这个两个数值来确定BarGraphView的大小。

(2)Layout(布局)

这个过程只在View容器(ViewGroup及其子类)有用,因为非容器类View在屏幕中的位置操作由父控件来决定,所以不需要覆写onLayout()方法。

(3)Draw(绘制)

最后绘制View的过程,在这个过程里主要通过Paint对象在Canvas上面绘制相应图像,最终把View展现在屏幕上。 对于自定义View来说,通常需要覆写onDraw()方法绘制View。

    @Override
    public void onDraw(Canvas canvas) {
    }
该方法提供了一块画布,我们只需要创建一个画笔在画布上绘图案即可。


好了,了解了上述过程,接下来我们开始实现BarGraphView。

BarGraphView主要代码集中在Draw的过程,通过onDraw方法把统计图绘制到屏幕上来。

经过分析,把柱状图分为以下几部分

1.横/纵坐标轴

2.横/纵坐标轴刻度线

3.横/纵坐标轴刻度值

4.横/纵坐标轴箭头

5.标题

6.柱状图

针对不同部分利用drawLine()(画直线)、drawText()(画文字)、drawPath()(画多边形)以及drawRect()(画矩形)的方法分别绘制相应图案。

以下是BarGraphView类代码,可以直接看注释。

package com.eleven.demo.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

import com.eleven.demo.R;

/**
 * Created by Eleven on 2015/5/3.
 */
public class BarGraphView extends View {

    private final String TAG = BarGraphView.class.getName();
    //画笔
    private Paint mPaint;
    //标题
    private String title;
    //标题颜色
    private int titleColor;
    //标题大小
    private float titleSize;
    //X坐标轴最大值
    private float maxAxisValueX = 900;
    //X坐标轴刻度线数量
    private int axisDivideSizeX = 9;
    //Y坐标轴最大值
    private float maxAxisValueY = 700;
    //Y坐标轴刻度线数量
    private int axisDivideSizeY = 7;
    //视图宽度
    private int width;
    //视图高度
    private int height;
    //坐标原点位置
    private final int originX = 100;
    private final int originY = 800;
    //柱状图数据
    private int columnInfo[][];

    public BarGraphView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //创建画笔
        mPaint = new Paint();
        //获取配置的属性值
        TypedArray mArray = context.obtainStyledAttributes(attrs, R.styleable.BarGraphView);
        title = mArray.getString(R.styleable.BarGraphView_barGraph_title);
        titleColor = mArray.getColor(R.styleable.BarGraphView_barGraph_titleColor, Color.BLACK);
        titleSize = mArray.getDimension(R.styleable.BarGraphView_barGraph_titleSize, 36);
    }

    /**
     * 设置X轴的最大值及刻度线数量(包括0坐标刻度)
     *
     * @param maxValue   X轴的最大值
     * @param divideSize 刻度线数量
     */
    public void setAxisX(float maxValue, int divideSize) {
        maxAxisValueX = maxValue;
        axisDivideSizeX = divideSize;
    }

    /**
     * 设置Y轴的最大值及刻度线数量(包括0坐标刻度)
     *
     * @param maxValue   Y轴的最大值
     * @param divideSize 刻度线数量
     */
    public void setAxisY(float maxValue, int divideSize) {
        maxAxisValueY = maxValue;
        axisDivideSizeY = divideSize;
    }

    /**
     * 设置柱状图数据
     *
     * @param columnInfo
     */
    public void setColumnInfo(int[][] columnInfo) {
        this.columnInfo = columnInfo;
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec) - 200;
        height = MeasureSpec.getSize(heightMeasureSpec) - 800;
    }

    @Override
    public void onDraw(Canvas canvas) {
        drawAxisX(canvas, mPaint);
        drawAxisY(canvas, mPaint);
        drawAxisScaleMarkX(canvas, mPaint);
        drawAxisScaleMarkY(canvas, mPaint);
        drawAxisArrowsX(canvas, mPaint);
        drawAxisArrowsY(canvas, mPaint);
        drawAxisScaleMarkValueX(canvas, mPaint);
        drawAxisScaleMarkValueY(canvas, mPaint);
        drawColumn(canvas, mPaint);
        drawTitle(canvas, mPaint);
    }

    /**
     * 绘制横坐标轴(X轴)
     *
     * @param canvas
     * @param paint
     */
    private void drawAxisX(Canvas canvas, Paint paint) {
        paint.setColor(Color.BLACK);
        //设置画笔宽度
        paint.setStrokeWidth(5);
        //设置画笔抗锯齿
        paint.setAntiAlias(true);
        //画横轴(X)
        canvas.drawLine(originX, originY, originX + width, originY, paint);
    }

    /**
     * 绘制纵坐标轴(Y轴)
     *
     * @param canvas
     * @param paint
     */
    private void drawAxisY(Canvas canvas, Paint paint) {
        //画竖轴(Y)
        canvas.drawLine(originX, originY, originX, originY - height, paint);//参数说明:起始点左边x,y,终点坐标x,y,画笔
    }


    /**
     * 绘制横坐标轴刻度线(X轴)
     *
     * @param canvas
     * @param paint
     */
    private void drawAxisScaleMarkX(Canvas canvas, Paint paint) {
        float cellWidth = width / axisDivideSizeX;
        for (int i = 0; i 


MainActivity的布局文件:



    


MainActivity中使用

public class MainActivity extends ActionBarActivity {
    private BarGraphView mBarGraphView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView(){
        mBarGraphView = (BarGraphView)findViewById(R.id.custom_view);
        mBarGraphView.setAxisX(900, 9);
        mBarGraphView.setAxisY(700,7);

        int columnInfo[][] = new int[][]{{600, Color.BLUE},{500, Color.GREEN},{400, Color.RED},{300, Color.BLUE},
                {500, Color.YELLOW},{300, Color.LTGRAY},{200, Color.BLUE}};
        mBarGraphView.setColumnInfo(columnInfo);
    }


该自定义View的实现中使用了自定义属性的方式定义了三个属性值,关于attrs.xml文件的使用方式参考 http://blog.csdn.net/jiangwei0910410003/article/details/17006087


Android自定义View------柱状统计图


推荐阅读
  • 本文探讨了如何通过最小生成树(MST)来计算严格次小生成树。在处理过程中,需特别注意所有边权重相等的情况,以避免错误。我们首先构建最小生成树,然后枚举每条非树边,检查其是否能形成更优的次小生成树。 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
  • 本文介绍如何使用 NSTimer 实现倒计时功能,详细讲解了初始化方法、参数配置以及具体实现步骤。通过示例代码展示如何创建和管理定时器,确保在指定时间间隔内执行特定任务。 ... [详细]
  • 本文介绍了在Windows环境下使用pydoc工具的方法,并详细解释了如何通过命令行和浏览器查看Python内置函数的文档。此外,还提供了关于raw_input和open函数的具体用法和功能说明。 ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 2023 ARM嵌入式系统全国技术巡讲旨在分享ARM公司在半导体知识产权(IP)领域的最新进展。作为全球领先的IP提供商,ARM在嵌入式处理器市场占据主导地位,其产品广泛应用于90%以上的嵌入式设备中。此次巡讲将邀请来自ARM、飞思卡尔以及华清远见教育集团的行业专家,共同探讨当前嵌入式系统的前沿技术和应用。 ... [详细]
  • Android 九宫格布局详解及实现:人人网应用示例
    本文深入探讨了人人网Android应用中独特的九宫格布局设计,解析其背后的GridView实现原理,并提供详细的代码示例。这种布局方式不仅美观大方,而且在现代Android应用中较为少见,值得开发者借鉴。 ... [详细]
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • 本文详细介绍了如何通过命令行启动MySQL服务,包括打开命令提示符窗口、进入MySQL的bin目录、输入正确的连接命令以及注意事项。文中还提供了更多相关命令的资源链接。 ... [详细]
author-avatar
冷鹰一诺_412
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有