V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
ChefIsAwesome
V2EX  ›  问与答

ios / android 程序里头,不同 view 之间的切换是怎样的机制

  •  
  •   ChefIsAwesome · 2016-04-08 09:35:03 +08:00 · 1645 次点击
    这是一个创建于 3145 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在做单页面的 web app ,处理不同 view 之间的切换折磨死我了。想听听其他平台是怎么做的。

    比方讲 app 是这样一个树形结构:

    {
      电视剧: {
        美剧,
        日剧,
      },
    
      电影: {
        中国电影,
        美国电影,
      }
    }
    

    刚进入程序的时候,我在电视剧这个 view 。

    点击美剧,新的 view 出来。这个新的 view 是在点击的时候创建并且渲染的吗?不管 ios 还是 android ,几乎都是点击的瞬间新的 view 就以动画的方式进来了,如果是新创建的,那渲染速度岂不是非常快。

    切换到电影,进入中国电影,再切换回电视剧,这时候我还在美剧这个 view :

    • 点击后退,后退到的是电视剧。也就是说后退是回到当前 view 的上一级,而不是之前的 view 。回到上一级这个机制是需要开发者写死后退的位置,还是需要开发者提供系统一个像上面那样的树形机构,又或者系统智能到帮你搞定一切?

    • 从美剧后退到电视剧之后,之前电视剧 view 的各种状态没有变。这时候再进入美剧,美剧 view 的状态丢失了。看上去像是系统保存了一个栈 [viewA, viewB, viewC...] 。只有栈尾的 view 会被显示,之前的都被隐藏着。回到上一级就是 pop 掉最后一个。进入新 view 就是往里头 push 一个。 push 进去的新东西会被重新渲染。重新渲染丢状态,而隐藏不会。所以回到上一级不会丢状态。但是在电视剧和电影两个大区块之间切换的时候不会出现丢状态的情况。所以我猜想可能系统对树的每一个分支都单独保存了这么一个栈?

    第 1 条附言  ·  2016-04-08 13:13:59 +08:00

    从楼下的发言看,安卓跟 ios 上做这些事情都很容易。web 不一样了。拿现在流行的 react 搭配 react-router 为例:

    一个 url 对应一个 view,view 跳转就是 url 跳转:

    • 一次只有一个 view 存在,前进后退都是重新渲染,速度慢,实现不了流畅的过度效果。
    • 之前的 view 被销毁,想保存状态得自己实现,而且不是所有的状态都可以获取。
    • 后退总是回到上一个 url,而不是上一级的 view。

    总而言之,体验各种不好。作为开发者,又没什么好的办法解决。

    5 条回复    2016-04-08 11:21:12 +08:00
    Shura
        1
    Shura  
       2016-04-08 09:41:09 +08:00 via Android   ❤️ 1
    Android 有个后退栈,和你打开 activity 的顺序有关
    wohenyingyu01
        2
    wohenyingyu01  
       2016-04-08 10:28:31 +08:00 via iPhone   ❤️ 1
    要看你怎么切了,安卓里面如果只切 fragment 不切 activity 的话,完全可以在 activity 的里全部预先载入好,随便你切都不会重新加载,需要自己管理历史栈或者直接无视,切 activity 就是切了才渲染,系统自动帮你加入栈,也可以自定义后退按钮的效果。
    ios 里面也有栈,好像需要有 navigation controller 的界面才可以被 push ,被 push 后有特定效果,比如左滑后退,基本全部是系统帮你管理,或者直接用 insert subview 的方式手动切换
    orange9
        3
    orange9  
       2016-04-08 11:01:22 +08:00   ❤️ 1
    android 的话 viewpager+fragment 默认预加载 源代码显示最少为 1
    hahasong
        4
    hahasong  
       2016-04-08 11:18:09 +08:00   ❤️ 1
    每个安卓应用有一个回退栈,系统维护栈,后进先出, A 调起 B , B 切出去返回 A 的时候, B 的状态是不用记录的, A 的会被记录,因为 A 还有恢复的可能性, B 不会恢复了。如果 B 上的操作对 A 的显示会有影响,就需要 B 和 A 通信,告诉 A 恢复的时候去更新 UI 。有个 OnActivityResult 回调方法。现在流行用 2 楼说的 Fragment 片段, Activity 不变,页面不销毁,只是内嵌的 Fragment 在切换, Fragment 也有一个回退栈,需要自己主动选择加入。同时 Fragment 之前也有通信的方法, Fragment 和父 Activity 之间都有通信方法

    ios 则是继承 NavigateViewController 来实现在多级 view 之前切换,它维护了一个 view 的数组,相当于安卓的回退栈,数组的最后一个 view 总是当前被显示的。 view 之前的切换,该 viewController 的实例是一直存在的,所以数据都在,需要更新显示,就调对应 view 的 setNeedDisplay 方法更新一下数据
    hahasong
        5
    hahasong  
       2016-04-08 11:21:12 +08:00
    @hahasong 有错字,前=间。总之就是移动端,很多东西都是系统帮你做了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2605 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:26 · PVG 12:26 · LAX 20:26 · JFK 23:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.