Android 创建一个可拖拽图表-第一部分

来源:互联网 发布:淘宝店标志设计app 编辑:程序博客网 时间:2024/05/17 06:05

 

这篇文章将讲述如何通过将部件放在单元格上来创建一个简单的2D图表。

首先你需要一个具有SurfaceView的Activity和一个用来触发画图的线程。如果读者不了解这些基础内容,请先行阅读我的文章series on 2d graphics。

让我们从绘图的最小单元—单元格开始。

每一个单元格都需要一个背景色和唯一的标识ID。

 

 

 

 

 

在第32行我们可以看到是如何画单元格的。变量_cellSize是一个CellMap类的静态成员变量,后面将会介绍。其它代码部分读者应该已经清楚了。

下一个我们需要能触发画图函数onDraw()的线程。你应当已经阅读过我写的关于SurfaceViews的系列文章,下面代码只是这一系列当中普通的一部分。

 

 

 

 

在我们进入绘图之前最后一项准备是我们的Activity.这里也没有什么新东西:

 

 

 

 

现在我们可以进入真正的绘图了。

我们需要创建一个类继承自SurfaceView并且继承SurfaceHolder.Callback接口。同时我们还要为Callback接口和onDraw()函数重写所需的函数。.在这些接口函数中我们将会管理线程,同时我们还要添加在Cell类中用到的_cellSize变量。

 

 

 

 

 

如果你运行这个程序,会看到黑屏,不过这是正常的。

我们要怎样实现一个表呢?我们应该使用一个可以实现图表接口的类。这就需要提到哈希表。

 

 

 

 

 

哈希表只有一个维度,因此我们需要组合两个哈希表来实现二维。一个用来存储行,一个用来存储列。

这是二维哈希表的声明,让我们把它分离开来看为什么我们要以这种方式来使用它。

 

 

 

 

 

这代表由一系列行组成的哈希表。整型参量Integer作为索引来实现根据y坐标定位到某一行。

下面让我们将单元格填入这个图表:

 

 

 

 

我们需要首先定义a_mapSize来定义行列的数量。我们还需要一个绘图对象来将它传递给我们的单元格onDraw()函数。之后在代码的25到32行我们有一个用来计数的变量id以及两层循环。外层循环代表我们按行为单位遍历,内层循环实现向每一行填入单元格。在第28行是将单元格填入各行,第30行是将每一行加入整个哈希表。虽然创建了这个图,但是还不足以使它显示。我们还需要重写onDraw()函数来逐个画出这些单元格。

 

 

 

 

在这里我们看到也是两层循环。这一次是遍历整个哈希表然后在正确的位置绘制每个单元格。一行内单元格都有相同的y坐标,因此我们在遍历一行内单元格时只需计算一次y坐标。每行的y坐标如下所示:0*30=0,1*30=30,2*30=60等等。

在内层循环中我们为一行内每个单元格计算x坐标,每个单元格的x坐标如下所示:0*30=0,1*30=30,2*30=60等等。

然后我们将单元格绘制出来。我们的绘制函数也会同时显示单元格的标识ID,正如下面所示的那样

编译并运行后结果如下。我们的程序绘制10*10的单元格,因为在我的仿真器上绘制100*100的单元格需要将近15秒钟。

 

 

 

为了能够滚动页面,我们需要处理触摸事件

 

 

 

 

 

首先我们需要定义整型变量_xTouch, _yTouch来存储我们最后一次触碰的位置,其次需要两个整型变量_xOffset, _yOffset来存储我们计算得到的位移。为了区分点击和移动,我们需要一个布尔型标志_isMoving..

当触碰事件发生,这个事件的初始标志都会是ACTION_DOWN。这时,前面提到的标志_isMoving会重置为false而且触碰位置将会存储下来。之后有两种不同的情况可能发生:一个是我们在屏幕上随意移动手指,另一个是我们抬起手指松开触碰,即点击。

首先介绍点击情况:这时事件标志ACTION_UP会发生,这时标志_isMoving处于false状态,之后我们进入if代码模块。我们根据位移量计算行列位置。之后我们将行列位置除以每个单元格的大小_cellSize,由于我们的哈希表下标是从0开始的,所以将前面除法得到的值再减一就得到了我们触碰的单元格在每一行和每一列中的编号,之后我们会给出一个包含该单元格的id的提示。

对于移动手指的情况:事件标志ACTION_MOVE会发生,标志_isMoving置True。这样当我们抬起手指时,上面提到的包含单元格id的提示不会出现。

下面我们计算整个图表的位移。重要的减法命令可以保证图向手指移动的相反方向移动。之后的if/else模块是保证当移动手指时,你不会看到图外部区域的空白。这是因为我们并没有画背景或其他东西在图以外区域,如果我们滚动区域超过图的范围,我们可以看到许多显示错误(可以将_mapSize修改为小值,比如10或者更小来测试一下)。最后在49、50行我们需要将触碰位置存储下来。

为了使滚动页面能够工作,我们需要修改onDraw()函数,将其中坐标的计算式都减去前面得到的位移量。

 

 

 

 

可以看到在15到19行,我们减去位移量。

现在你可以编译并运行这个程序。在你确定该程序运行正常后,你可以试一试范围为100*100或更大的图表,之后你可以看到程序绘图延迟非常严重。

在下一个部分中,我将展示如何在一个300*300单元格的图表上实现流畅的滚动页面。

eclipse 工程源码:ScrollMap

原文链接:http://www.droidnova.com/create-a-scrollable-map-with-cells-part-i,654.html

原作者:Martin

原创粉丝点击