V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xu33
V2EX  ›  程序员

有做安卓 Launcer 开发的同学吗,想知道安卓桌面大小不一的元素在拖动位置时,计算变化是用的什么算法?

  •  
  •   xu33 · 2015-08-27 21:39:30 +08:00 · 3200 次点击
    这是一个创建于 3382 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我在网上搜索 ,不知道用什么关键词来找

    9 条回复    2015-08-28 10:59:24 +08:00
    xhuuanniqege
        1
    xhuuanniqege  
       2015-08-27 22:18:33 +08:00 via Android
    计算什么变化?
    lzhtony
        2
    lzhtony  
       2015-08-27 22:23:04 +08:00
    launcher 的各种功能可以看源码.网络上有挺多的 launcher 源码解读的.如果没找到你要的,可以自己看.
    xu33
        3
    xu33  
    OP
       2015-08-27 23:06:41 +08:00
    @xhuuanniqege 就是拖拽移动图标,和别的图标发生碰撞,移动的规则
    ljbha007
        4
    ljbha007  
       2015-08-28 00:31:29 +08:00
    @xu33 碰撞可以用简单的计算中心点距离

    移动的规则可以这样(不考虑 widget ):
    1.每个格子从左上往右下编号
    2.用数组存图标 数组索引对应每个格子 用来表示哪个图标在哪个格子
    3.每次拖动的触摸事件时 或者 按固定频率访问被拖动的图标的位置 也就是触摸点的位置
    4.计算每个中心点到触摸点的位置 如果小于某个阈值就触发第 5 步(记为点 a ) 阈值应该小于相邻两个中心店距离的一半(防止两个点同时触发第 5 步)
    5.取点 a 的索引 遍历索引大于等于 a 的图标 将其索引往后移动 1 格
    6.如果遇到空白格子则退出
    7.最后(索引值最大的)一个图标后移时如果大于了数组的长度 则从数组中删除 然后放到下一页的数组的第一个(如果下一页第一个格子已有图标 则对下一页的数组再递归一次 5 ~ 6 的操作)
    ljbha007
        5
    ljbha007  
       2015-08-28 00:32:23 +08:00
    绘图的时候就不考虑拖动 每次都根据数组的值把图标绘制在对应的格子的中心点
    xhuuanniqege
        6
    xhuuanniqege  
       2015-08-28 00:36:28 +08:00
    @xu33 具体的代码,你可以在 Launcher3 源码中 CellLayout 类中找到,我看了一下,是 createAreaForResize 方法。具体怎么实现的我忘了,你自己看看源码吧。
    vileer
        7
    vileer  
       2015-08-28 00:57:09 +08:00
    在 go 桌面干过两年, celllayout 有你要的一切,主要是按照格子来算的,虽然你看到的是不规则的图形,例如 widget 和图标,但是挤压时还是按照格子来算
    miniwoodman
        8
    miniwoodman  
       2015-08-28 02:01:17 +08:00
    这个可以简化为二位数组的元素移动, 比如屏幕有 4×5 行图标, 虽然安卓屏幕控件有 1x2 1x3 2x2 2x3 ...等不同的尺寸, 但是处理起来和 1x1 的图标差不多, 可以看作是几个图标同时移动。

    首先定义一个 4×5 的二位数组 screen_gird , 让后将当前屏幕上的图标 ID 按对应位置填写进去。
    如果发生图标 /控件的移动动作时,就复制这个 4×5 的数组 screen_gird_target ,作为目标缓冲区(还可以作为动画效果的参照数据),
    然后将当前移动对象的原始位置清空(写 0 ), 再根据图标 /控件当前悬停的位置,计算出有几个数组元素需要让位,把它们写入一个一维数组列表 list_tmp , 让后让控件落在空出的位置上, 最后从下向上逐行扫描数组 screen_gird_target ,将 list_tmp 的元素逐个写入到空位中去。

    以上是算法的第一个版本,满足基本的图标给控件让位,但很不完善,图标应该就近让位,而不是飞到最下行去,还没考虑到控件给控件让位的情况。

    可以根据情况逐渐改进,比如可以定义一个常量作为不可以移动的标志, 将 screen_gird_target 中符合控件轮廓而需要占用的目标位置以这个常量逐次写入 , 全部写入后,控件就可以落下。
    每一次写入都要求占用目标位置的元素(图标或控件)执行一次让位移动动作,这样一来这个移动让位的函数就应该能够递归调用,这些函数的递归调用实例都共享一个 screen_gird_target ,遇到不可移动标志就跳过寻找可以移动的空位。最后还要返回让位是否成功的标志,如果其中任意一个不成功,就说明无法完成这个拖动操作。
    xu33
        9
    xu33  
    OP
       2015-08-28 10:59:24 +08:00
    @miniwoodman 谢谢 我学习下
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2718 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 10:06 · PVG 18:06 · LAX 02:06 · JFK 05:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.