本文原创http://blog.csdn.net/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的布局结构就已经大体说完了。对于每个控件的具体作用,本人也正在研究中,有不懂的一起讨论,有不足的地方请指正,一起学习。