这是基于android launcher2.2中的workspace实现的横向滚动,熟悉launcher的朋友对workspace一定不会陌生,它在launcher中拥有着相当的作用,你启动android手机时左右屏幕的滚动就是依靠它来实现的,这个例子中有涉及到Custom layout的知识,例子中的显示所有application的容器也是通过自定义来实现,这个类叫AppPanel.java下面会对这个类的详细介绍;实现滚动的类也就是从launcher2.2中workspace抽取出来实现滚动的类叫ScrollPanel.java,除此之外还有一个布局文件,这个布局文件相对来说较简单app_item.xml用于规范显示的application。我们首先分析例子实现的几个部分,分别为:
首先,加载所有app,通过Intent构建查询条件,然后由PackageManager调用queryIntentActivities方法来执行查询,查询返回的结果返回的是以ResolveInfo类为泛型的List集合,加载app可以在activity中实现。
其次,加载符合条件的app后,紧接着的是将这些app通过custom layout来放置这些app,自定义布局有两个比较重要的地方,通常需要做一次操作时,继承Viewgroup来实现而不是继承View。第一是重载onMeasure方法,在这里你需要测量你的childView放在这个容器里面需要多大的空间,在测量childView的时候MeasureSpec有三种模式供你选择分别是UNSPECIFIED,EXACTLY,AT_MOST,所有的childView测量完成之后,需要将这些childView显示在这个viewgroup容器里面;第二就是重载onlayout方法来实现布局,这部分的实现是在AppPanel中完成。
最后是实现滚动了,也是这个例子中比较重要的一部分,滚动的原理我画了一个很简单的草图供大家理解:
其中灰色的矩形是ScrollPanel这个类来控制的,红色的矩形其实就是AppPanel容器,到这里的时候或许会忍不住的问怎么实现滚动呢?其实实现滚动我们还漏了一重要的角色就是Scroller类,Scroll提供了许多方法供你使用,其中scrollTO(), startScroll(),scrollBy()在例子中需要使用的,括号里面还有些参数没有列出。在滚动的时候灰色矩形是没有滚动的,滚动的是红色的矩形,需要重写onInterceptTouchEvent和onTouchEvent方法,在launcher中onInterceptTouchEvent是充当一个分发事件的角色,你所有的事件(手指按下,长按屏幕,手指放开等)这些操作都会通过onInterceptTouchEvent来拦截,拦截之后在分发给相应的childView,在这个方法里面需要记录手指开始按下的位置。滚动的时候这里需要特别提醒的是,当滚动到一个屏幕的50%以上手指离开时,页面切换不会很彻底,而是停留在两个屏幕之间。所以当用户抬起手指时程序需判断一下移动到下一个完整的屏幕还有多大距离,然后让 ScrollPanel这个 View 再移动这个距离一遍完整的切换到下一页。在这个移动的过程中,为了有一个平滑的感觉,不能一下就移动这个距离,而是需要给一定的时间间隔,在这个时间段里逐渐的移动到位,所以这里我们使用 Scroller 类的方法实现逐渐的移动。
整体的效果图:
最后分享一些其他的文档连接
custom layout:http://developer.android.com/guide/topics/ui/custom-components.html
android动画理解:http://www.ibm.com/developerworks/cn/opensource/os-cn-android-anmt2/index.html?ca=drs-这里面有对workspace详细解释,值得一看!