开源 Android InDoorView 室内选位控件,助力快速开发 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
karonl
V2EX    Android

开源 Android InDoorView 室内选位控件,助力快速开发

  •  
  •   karonl 2016-06-26 00:10:56 +08:00 13737 次点击
    这是一个创建于 3440 天前的主题,其中的信息可能已经有所发展或是发生改变。

    介绍

    先给个简单的介绍,最近接到个 case ,大概是开发一个可以室内选工位的 app 。这我们很容易想到电影院的选座位,可有点不一样,因为每个区域都是不同大小并且位置不一,而我们手上的材料只有一张标识有区域的 jpg 地图。一开始我使用引擎来做,结果可想而知,为了个简单功能引入整个库非常不明智。

    应用场景:

    电影院选座、商场购物地图、展位摊位在线预定、办公场地租赁工位等需要操作不规则区域的功能。

    示例图

    原理:

    把读取地图底图 bitmap 和使用 Paint 的钢笔路径集合一同绘制到一个 canvas 上保存,并通过继承 SurfaceView 把 canvas 绘制到双缓画布中,通过 canvas.drawBitmap 实现缩放和移动,重写 view 点击事件结合 Region 判断点击坐标位于哪个区域内,再通过接口反馈事件。

    采用把所有图案内容事先缓存到 canvas 的方法,使用非 UI 线程进行绘制,可实现每秒 60 次左右的界面绘制,实现流畅的移动和缩放操作;在没交互情况下,暂停绘制及刷新以节约计算资源。

    特性:

    1. 性能较强,绘制达到 60 帧上下
    2. 支持缩放以及拖动
    3. 直接使用原生 SurfaceView ,无需导入庞大的引擎库

    Github:

    https://github.com/karonl/InDoorSurfaceView (thanks for your star)

    Demo:

    直接使用 Android Studio 导入工程即可运行

    如何导入 InDoorView 库:

    1. clone 到本地
    2. 复制 InDoorView 文件夹到目标项目的根目录 (InDoorView 使用的是 apply plugin: 'com.android.library')
    3. 在 settings.gradle 文件中 include ':InDoorView'
    4. 在主模块(一般是 app 文件夹)中的 build.gradle 中添加依赖
      dependencies { compile project(':InDoorView') } 
    5. 点击 Sync 进行构建
    6. 根目录的 src 是 demo ,可做参考

    注:直接导入工程是 demo ,可直接运行测试

    如何使用:

    1. 初始化 在 xml 文件中使用进行声明

      <com.karonl.instance.InDoorView android:id="@+id/surface" android:layout_width="match_parent" android:layout_height="match_parent" /> 

      在对应的 activity 中进行引用,并通过设置适配器,把底图和区域 list 填入,并 refreshData();

      InDoorSurfaceView view = (InDoorSurfaceView)findViewById(R.id.surface); DataAdapter adapter = new DataAdapter(); view.setAdapter(adapter);//初始化 adapter.setBmp(bmp);//设置图片(底图) adapter.setList(list);//设置数组(图上的可点区域) adapter.refreshData(); 
    2. 上面代码的 list 的具体设置看这里:

      (输入钢笔路径相对于图片左上角的节点坐标)

      //每个图案的节点坐标集合 private List<PointF> getList(){ float density = getResources().getDisplayMetrics().density; List<PointF> pointList = new ArrayList<>(); pointList.add(new PointF(99.1f * density,673.1f * density)); pointList.add(new PointF(222.1f * density,670.1f * density)); pointList.add(new PointF(227.1f * density,327.1f * density)); pointList.add(new PointF(94.1f * density,321.1f * density)); pointList.add(new PointF(100.1f * density,674.1f * density)); return pointList; } //区域列表 private void getUnitList(){ PathUnit unit = new PathUnit(getList());//把节点换成一个 PathUnit 元素 unit.setName("John Market");//设置元素的名字 unitList.add(unit);//添加到区域列表 } 

      注:从资源读取的图片对应的坐标要乘上 desity ,网络加载的图片则不用

    3. 接口说明: 通过该接口可以返回点击到的区域的 PathUnit 元素,可通过此来获取区域名字等信息

      view.setOnClickMapListener(new InDoorSurfaceView.onClickMapListener() { @Override public void onClick(PathUnit region) { //读取 pathunit } } 

      该接口是 fps 帧率

      view.onFramesListener(new InDoorSurfaceView.FramesListener() { @Override public void onRefresh(float number) { //帧率 } } 

    环境:

    compileSdkVersion 24 buildToolsVersion "24.0.0" minSdkVersion 16 gradle plugin:gradle:2.1.2 

    另外:

    1. 如果你有项目使用了该库也可以告知我,我将把你的 app 作为示例
    2. 如果你有建议或者想法,也欢迎告知我,这将让开源代码变得更好
    3. 如果程序有 bug 和改善方法,感谢提 Issues ,有劳指教!
    第 1 条附言    2016-06-26 02:05:19 +08:00
    为每个区域分别设定坐标的时候,衡量 x , y 确实繁琐。不过已经为此开发了个前端版本的 “绘制画板”,事先导入图片,通过圈选出所有区域,最后生成 json 。当然你也可以自己写个协助程序,或者等我开源。
    6 条回复    2016-06-26 15:24:44 +08:00
    kenshinhu
        1
    kenshinhu  
       2016-06-26 00:21:57 +08:00
    这个之前也有尝试过用 svg 来实现,但代价是需求美工将图用 AI 来绘,之后手动在对应的区域映射指定的事件
    xiezuan
        2
    xiezuan  
       2016-06-26 00:30:44 +08:00 via iPhone
    好牛,看下
    Ervin
        3
    Ervin  
       2016-06-26 03:32:26 +08:00 via Android
    666666
    kslr
        4
    kslr  
       2016-06-26 06:13:25 +08:00 via Android
    Nice
    run2
        5
    run2  
       2016-06-26 15:18:03 +08:00
    SVG+JSON 的数据源更方便点吧。。。
    区块有 ID , json 直接对应 ID
    karonl
        6
    karonl  
    OP
       2016-06-26 15:24:44 +08:00
    @sobigfish 这个提议可以,回头研究一下
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1024 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 21ms UTC 18:18 PVG 02:18 LAX 10:18 JFK 13:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86