自定义地图开发(一)

摘要:
现在,整理地图模块。在第一幅图片中,彩色的用作地图背景,后两幅不规则的用作地图元素。我很高兴。我自豪地将屏幕大小调整到2000*2000,不再担心视图缩小。接下来,我们将地图数据填充到XML文件中。下图是一个示例。如果我们想知道第一层的坐标和大小。

前言:

oh my lord,憋了好久了。纷纷扰扰的闹剧算是结束了,关于这个项目的任务也暂停一段时间。趁现在,好好的把地图模块整理一下。

要做的项目中,有一个功能是校园地图。但是不希望用现有的地图SDK来展示,故此,我只好自己写一个简单的模块来展示一张平面图。

先放一张效果图吧,当时匆忙,很多地方未完善,但最终的效果应该是这个样子的:

自定义地图开发(一)第1张

至于地图上那个图片,是用来做定位时的准星的……不要在意这些细节。


正文

好的,现在,咱们的教程,正式开始:

本章教程中,我需要一个组件,可以用来监听不规则形状的地图元件,并且可以在点击他的时候做一些响应。

为了简化开发步骤,我做了以下简化地图:

地图素材--->自定义地图开发(一)第2张  地图--->自定义地图开发(一)第3张...美观什么的不要在意。

第一张图中,花花绿绿的当做地图背景(1000*1000),后两个不规则的当做地图元件。拼起来,做成后面的地图。


1.那么第一个问题出现了:我的屏幕是480*800,如何展示一张1000*1000的图呢?

在实验过程中,我们发现,无论layout_width怎么设置,系统都会将其强制转换为屏幕大小。这个问题,我头疼了好久。最后终于发现,问题的答案很简单~

1 @Override
2     protected voidonCreate(Bundle savedInstanceState) {
3         this.getWindow().setLayout(2000, 2000);//关键代码
4         super.onCreate(savedInstanceState);
5 setContentView(R.layout.activity_main);
6     }

既然屏幕太小,把屏幕值调大些就好了。啊!从此天高任鸟飞,一报憋死人之仇。我心里大大快乐,得意洋洋的将屏幕大小调成了2000*2000,再也不担心View被缩水啦~

接下来,我们将地图数据填写到XML文件中。


2.卓克,填写地图数据时,如何快速的知道地图元件在地图上的位置呢?

首先,打开PS,加载图形。以下图为例,如果我们想知道第一个图层(正方形黑块)的坐标和大小。

1:选中第一个图层,使其变为高亮状态(如下图的蓝色)。

2:按Ctrl+T。

3:按F8打开信息窗口。这时可以看到,坐标和宽高都显示出来了。

自定义地图开发(一)第4张自定义地图开发(一)第5张

另外,在XML文件中设置位置的时候,通常一些超出屏幕的imageView看不到设置效果。

为了更好的实时看到效果,我们可以这样设置:

自定义地图开发(一)第6张

瞧到没,换个超大分辨率的来展示XML就好了~


3.卓克,地图数据填完了,也展示了出来,可是屏幕大小该是多少还是多少,地图显示不全啊!

那好,咱想个办法,让咱的地图可以动起来。……OnTouchListener,即拖图功能。

具体的实现,待会的源码里面有,从网上搜索“android开发 拖图”也有一大堆教程,在此不做赘述,只将实现原理简单一说:

实现原理,就是通过监听手指(触点)落下的位置、移动的位置来计算要让图片偏移的位置,然后用view.layout(l,t,r,b)方法让地图移动到指定位置。

我写过一个简单的拖图类,有兴趣的也可以下载下来,参考一下。


4,好了,你已经成功的将地图放进了程序里,并且可以自由拖动了,可是我们马上发现一个问题,当更新一个textView、显示/隐藏一个imageView的时候,地图完全乱了!

why! damn it! WTF!

不要悲伤,不要心急,答案让我告诉你……这个时候,我们需要用到一个方法,就是ViewGroup中的onLayout!

干嘛用的?就是固定子元件用的!

网上这么多好教程,不推荐给大家太可惜了:Android的onLayout、layout方法讲解

嘿嘿......谁敢说我懒!pia飞!

相信看了以上的博客,关于onLayout和layout,以及自定义ViewGroup都有所了解了。


5.这样的话,监听有冲突呀!甚至什么时候是点击,什么时候是拖动该怎么判断呢?

首先呢,判断拖动还是点击,可以这样来做:

1     private boolean shake = false, click = false;//手指抖动修正
2 @Override
3     public booleanonTouch(View v, MotionEvent event) {
4         switch(event.getAction()) {
5         caseMotionEvent.ACTION_DOWN:
6             click = true;//抖动校正
7             //记录触点按下时的位置
8             baseTX =event.getRawX();
9             baseTY =event.getRawY();
10             break;
11         caseMotionEvent.ACTION_MOVE:
12             //计算当前手指位置与初始位置间的偏移量
13             float sx = event.getRawX() -baseTX;
14             float sy = event.getRawY() -baseTY;
15 
16             //判断是否是抖动
17             shake = (Math.abs(sx) < shakeRange) && (Math.abs(sy) < shakeRange);// 注意用绝对值
18             if (shake) {// 抖动校正
19                 click = true;//抖动
20             } else {
21                 click = false;//拖动
22             }
23             break;
24         caseMotionEvent.ACTION_UP:
25            if (click) {
26                 click = false;
27                 //代码运行到这里,说明是点击动作。
28                 //可以在这里面写一些处理方法
29             }
30             break;
31         default:
32             break;
33 }
34 
35         return true;
36     }

唉,唯一的一大段代码献给了这么简单的一个小功能。算了,不管这些,继续探讨我们的思路。


6.可是,卓克,这样,咱也不知道什么时候点击了哪个元件呀!

ok,接下来咱讲讲怎么根据从onTouch中获取的坐标,判断点击没点到有颜色的区域。

首先,我们将这个坐标转化为相对于元件的坐标。

1     trueX = x - this.getChildAt(i).getLeft();
2     trueY = y - this.getChildAt(i).getTop();

得到相对于元件的坐标后,使用以下方法判断该点是否透明

1     pixel =bitmaps.get(i).getPixel(trueX, trueY);
2     if (pixel != 0) {//点击点不透明
3         //do something useful
4         break;
5     }

判断出点击到哪个图片,我们就可以对点击到的元件为所欲为咯~比如setAlpha、setVistbility之类的……

好的,目前为止所以的关键思路和代码都有了。自己动手,丰衣足食,让我们看看最终实现的效果吧:

自定义地图开发(一)第7张自定义地图开发(一)第8张自定义地图开发(一)第9张

半透明的地图元件在点击后变成了完全透明,而且无论是拖动还是在新线程中更新button的text布局丝毫不乱~


源码内附有详细的注释和使用方法(详细的有点过分……),敬请点击下载

好滴,这一章就到这吧。

下一章,将会添加百度地图lbs定位到咱们的程序里。觉得有帮助,可以关注啊、收藏啊、订阅啊、留言啊……之类的。

免责声明:文章转载自《自定义地图开发(一)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇cesium 雷达扫描(附源码下载)Unity进阶之ET网络游戏开发框架 02-ET的客户端启动流程分析下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

IIS 中 "另一个程序正在使用此文件,进程无法访问!"

然而,自从昨晚重新启动机器后,发现iis无法启动。手动启动并提示:“另一个程序正在使用此文件,进程无法访问它!”百度得知这是由港口冲突造成的。什么软件使用端口80?同时,我更改了iis的默认端口80,没问题。接下来,我想知道是哪一方秘密占用了端口80。但是,在执行上述命令后,我没有找到占用端口80的程序。我惊讶地发现没有人占用端口80。...

MySQL 字段类型占用空间

MySQL支持多种列类型:数值类型、日期/时间类型和字符串(字符)类型。)1或2个字节,取决于枚举值的个数SET(‘value1’,’value2’,…)1、2、3、4或者8个字节,取决于set成员的数目上表的M只是为了说明占用空间大小,在实际创建表中char、varchar,20指的是字符而不是字节;那么字符和字节的转换要看字符集,utf-8下,1字符=3...

vue+jspdf+html2canvas导出PDF文件

没有废话。首先,查看最终打印结果。我说最后打印的pdf文件看起来像这样。pdf文件的分页是通过设置jspdf实现的,但我暂时无法对文件内容进行分页。因为我们首先将需要打印的元素转换为画布,然后将画布转换为图像,然后将图像转换为pdf文件。...

Vue浏览器调试工具VueTools安装以及使用

ue-devtools是一款基于chrome浏览器的插件,用于vue应用的调试,这款vue调试神器可以极大地提高我们的调试效率。vue-devtools使用起来还是比较简单的,上手非常的容易,这里就细讲其使用说明了。安装方法二:这里以chrome浏览器为例:1、打开chrome网上应用店,搜索vue.js注:如果打不开页面需要代理选择第一个,点击添加至chr...

ORACLE无法删除当前连接用户

今天在做Oracle数据库是遇到ORACLE无法删除当前连接用户,经查找可用如下方法解决。SQL˃dropuseracascade;//删除用户以及用户表空间下所有对象用户已丢弃。...

实用小技巧:在键盘没有小键盘时怎么打开任务管理器

原创:转载请注明出处!我需要为我的工作买一个87键的机械键盘。当我打开任务管理器打开时,我经常使用Ctrl+Alt+;现在不行了。有几种方法可以打开任务管理器以查看当前任务状态:1.Ctrl+Alt+Delete,这与之前的Ctrl+Alt+Delete相同,效果相同;2.Ctrl+Shift+Esc也可以调出任务管理器;3.右键单击任务栏的空白区域,然后从...