本文原创http://blog.youkuaiyun.com/yanbin1079415046,转载请注明出处。
相信很多刚开始看ADW_Launcher童鞋都会有这样一种感觉,点开launcher的布局文件launcher.xml一看。天,全部是自定义的控件,瞬间心都拔凉拔凉的。总不可能一开始就一个控件一个控件的去看吧。今天我们就来看一看ADW_Launcher主页的布局文件。
首先,你得有一份源代码吧。可以参考本人的这篇文章:在eclipse中调试launcher模块以及已编译launcher源码两份。其次,为了更形象的分析launcher.xml,你应该要了解一下android自带的Hierarchy Viewer工具,可以参考这篇文章:Android 实用工具Hierarchy Viewer实战 。
好了,我们现在就开始来看一看launcher.xml。为了更好的说明,把launcher.xml的文件内容贴一下吧。其代码如下:
<?xml version="1.0" encoding="utf-8"?>
<com.android.ADW_launcher.DragLayer
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.ADW_launcher"
android:id="@+id/drag_layer"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- The workspace contains 5 screens of cells -->
<com.android.ADW_launcher.Workspace
android:id="@+id/workspace"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
launcher:defaultScreen="2">
</com.android.ADW_launcher.Workspace>
<ViewStub
android:id="@+id/stub_drawer"
android:inflatedId="@+id/all_apps_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<LinearLayout
android:id="@+id/drawer_toolbar"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="right|center_vertical"
android:layout_gravity="right|center_vertical">
<com.android.ADW_launcher.ActionButton
android:src="@drawable/rab_empty"
android:background="@drawable/rab_bg"
android:scaleType="center"
android:layout_width="wrap_content"
android:id="@+id/btn_rab"
launcher:ident="RAB"
android:layout_height="60dip"
/>
<com.android.ADW_launcher.ActionButton
android:src="@drawable/rab_empty"
android:background="@drawable/rab2_bg"
android:scaleType="center"
android:layout_width="wrap_content"
android:id="@+id/btn_rab2"
launcher:ident="RAB2"
android:layout_height="60dip"
/>
<ImageView
android:id="@+id/appsBg"
android:background="@drawable/handle"
android:layout_width="wrap_content"
android:layout_height="55dip"
/>
<com.android.ADW_launcher.ActionButton
android:src="@drawable/lab_empty"
android:background="@drawable/lab2_bg"
android:scaleType="center"
android:layout_width="wrap_content"
android:id="@+id/btn_lab2"
launcher:ident="LAB2"
android:layout_height="60dip"
/>
<com.android.ADW_launcher.ActionButton
android:src="@drawable/lab_empty"
android:background="@drawable/lab_bg"
android:scaleType="center"
android:layout_width="wrap_content"
android:id="@+id/btn_lab"
launcher:ident="LAB"
android:layout_height="60dip"
/>
</LinearLayout>
<ImageView
android:src="@drawable/home_arrows_left"
android:layout_height="wrap_content"
android:id="@+id/btn_scroll_left"
android:layout_width="wrap_content"
android:layout_gravity="bottom|right"
android:onClick="previousScreen"/>
<ImageView
android:src="@drawable/home_arrows_right"
android:layout_height="wrap_content"
android:id="@+id/btn_scroll_right"
android:layout_width="wrap_content"
android:layout_gravity="top|right"
android:onClick="nextScreen"/>
<com.android.ADW_launcher.SliderView
android:src="@drawable/handle_icon"
android:id="@+id/all_apps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/all_apps_view"
android:focusable="true"
android:clickable="true"
android:scaleType="center"
android:layout_gravity="right|center_vertical"
launcher:slideDirections="left"
launcher:targetDistance="45dip" />
<com.android.ADW_launcher.DeleteZone
android:src="@drawable/ic_delete"
android:background="@drawable/delete_zone_selector"
android:id="@+id/delete_zone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:layout_gravity="right|center_vertical"
android:visibility="invisible"
launcher:direction="vertical" />
<com.android.ADW_launcher.DockBar
android:id="@+id/dockbar"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_gravity="center_vertical|right"
launcher:position="right"
>
<com.android.ADW_launcher.MiniLauncher
android:background="@drawable/dockbar_bg"
android:id="@+id/mini_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
launcher:cellWidth="65dip"
launcher:cellHeight="48dip"
launcher:cells="6"
launcher:orientation="vertical"
android:padding="0dip"
/>
</com.android.ADW_launcher.DockBar>
<com.android.ADW_launcher.DesktopIndicator
android:id="@+id/desktop_indicator"
android:visibility="gone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</com.android.ADW_launcher.DragLayer>
通过Hierarchy Viewer工具,我们可以很清楚的看到launcher.xml的布局的结构图如下:
图一 launcher.xml布局结构图
对于其中的AllAppSlidingView,其图如下:
图2 AllAppSlidingView结构图
这里简单的对图解释一下。(由于只看了部分源码,这里引用这位哥们的一篇帖子进行说明。帖子地址如下:android_launcher的源码详细分析。
DragLayer.java继承自FrameLayout并且实现了DragController接口,负责拖动事件和事件分发。
Workspace.java继承自WidgetSpace(ViewGroup),实现DropTarget(可放置拖动对象的容器), DragSource(可拖动对象容器), DragScroller(左右拖动控制器), MultiTouchObjectCanvas()<Object>(可多点触控)四个接口。它是launcher启动时默认进入的桌面,里面包含若干个CellLayout,每个CellLayout代表一屏。CellLayout中可以放BubbleTextView,Search(自带搜索框),Folder(LiveFolder,UserFolder)和widget。这些信息被存放在/data/data/com.android.ADW_Launcher/databases/launcher.db 的favorites表下。关于favorites表下字段的含义,请参见这篇文章。文章地址:Android中ICS4.0源码Launcher启动流程分析【android源码Launcher系列一】。这里稍微补充一下,针对在AWD_Launcher。对于container字段,有六个可取的值。如下:
static final int CONTAINER_DESKTOP = -100; //应用程序(快捷方式)
static final int CONTAINER_DOCKBAR = -200;//MiniLauncher
static final int CONTAINER_LAB = -300;//ActionButton 1
static final int CONTAINER_RAB = -400;//ActionButton 3
static final int CONTAINER_LAB2 = -500; //ActionButton 2
static final int CONTAINER_RAB2 = -600; //ActionButton 4
ActionButton的CellX和CellY为 -1,widget的CellX和CellY为0。该值从0开始。
ViewStub是androidSDK中的控件。具体看文档。在ADW_Launcher中使用AllAppsSlidingView来填充它。AllAppsSlidingView继承自AdapterView<ApplicationsAdapter>类,并且实现OnItemClickListener, OnItemLongClickListener, DragSource(可拖动的对象), Drawer(用户可自定义【通过menu-桌面设置来体现】)四个接口。它将以GridView的方式,结合CounterTextView分屏展示所有用户安装和系统自带的应用程序。
LinearLayout 注意LinearLayout下面的两个ImageView,这里说的在LinearLayout的左边的意思是:这两个ImageView是在LinearLayout控件上面的左边和右边,也就是说这两个ImageView是在LinearLayout的"里面"的,而LinearLayout宽度使用的FILL_PARENT,因此它的宽度是占据整个屏幕宽度的。
ActionButton.java继承自CounterImageView(ImageView)并且实现了DropTarget, DragListener两个接口。它表示展示在托盘里的应用程序。
SliderView.java 继承自ImageView。它的作用就是当用户点击托盘中间的格子(主页)的时候,弹出对应的页面。SliderView也可以网上滑动,当它往上滑动到一定的距离时,DockBar就会占据LinearLayout的位置,并且显示 MiniLauncher。对于SliderView.java的介绍,请看我的另一篇文章(这几天给出)。
DeleteZone.java 继承自ImageView,实现DropTarget, DragController.DragListener两个接口。当用户长按桌面应用程序(快捷方式)的时候,会将其从favorites表中删除,因此就不会再显示在桌面上了。它占据着SliderView的区域。
DockBar.java 继承自LinearLayout,实现OnClickListener接口。当SliderView往上滑动到一定距离的时候显示。
DesktopIndicator.java继承自ViewGroup实现AnimationListener接口。它的作用是在屏幕滑动的时候实时的更新自己,以显示当前所在的屏幕位置。
到这里,launcher.xml的布局结构就已经大体说完了。对于每个控件的具体作用,本人也正在研究中,有不懂的一起讨论,有不足的地方请指正,一起学习。