我现在手头上的launcher的源码是基于android4.1的,其实4.0,4.1,4.2,乃至4.4的差距并不是很大,但是由于运行系统是4.1的,所以,最好还是基于4.1的版本来开发,由于原生的launcher(以后简称桌面好了,比Launcher打的快一点),今天的主要工作就是去掉原生桌面的某些东西(搜索栏目,竖条等),修改hotseat的排列方式。先来看看我的效果图吧(开发样机使用的是魅族MX,嘻嘻*-*):
因为程序是用于车载导航仪的,所以界面和一般的手机界面差别较大。改动也比较大,不过对于Launcher的分析修改都是通用的,大家也将就着看下去吧。这里也放一下原生桌面的样子:
接下来,我们就针对界面修改的地方做分析:
一、竖屏改横屏
这里其实没什么技术含量,就是修改manifest,找到android:screenOrientation这个属性,将其值修改为landscape即可
二、去除google search bar
因为是定制的车载导航需要的launcher,所以这个一直显示在顶栏的google search bar就显得比较讨厌了,肯定是要去掉的,那么,要怎么去掉呢,研究清楚了其实也不复杂:
1. Launcher2\res\layout\qsb_bar.xml中,
1 <include android:id="@+id/qsb_search_bar"
2 layout="@layout/search_bar"
3 android:visibility="gone" />
加入 android:visibility="gone"
2. packages\apps\Launcher2\res\layout-port\launcher.xml
1 <com.android.launcher2.DrawableStateProxyView
2 android:id="@+id/voice_button_proxy"
3 android:layout_width="80dp"
4 android:layout_height="@dimen/qsb_bar_height"
5 android:layout_gravity="top|right"
6 android:clickable="false" //modify this value to false
7 onClick="onClickVoiceButton"
8 android:importantForAccessibility="no"
9 launcher:sourceViewId="@+id/voice_button" />
android:clickable属性修改为"false"
3. Launcher2\src\com\android\launcher2\SearchDropTargetBar.java 中 onFinishInflate() 方法内,将mQSBSearchBarAnim 相关的部分作如下修改
1 // Create the various fade animations
2 if (mEnableDropDownDropTargets) {
3 mDropTargetBar.setTranslationY(-mBarHeight);
4 mDropTargetBarAnim = ObjectAnimator.ofFloat(mDropTargetBar, "translationY",
5 -mBarHeight, 0f);
6 mQSBSearchBarAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "translationY", -mBarHeight ,
7 -mBarHeight); //modify 3rd para to -mBarHeight
8 } else {
9 mDropTargetBar.setAlpha(0f);
10 mDropTargetBarAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 0f, 1f);
11 mQSBSearchBarAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 0f , 0f); //modify 3rd para to 0f;
12 }
4. 仍然是这只 java 文件,将showSearchBar 方法作如下修改:
1 public void showSearchBar(boolean animated) {
2
3 if (!mIsSearchBarHidden) return;
4 if (animated) {
5 prepareStartAnimation(mQSBSearchBar);
6 mQSBSearchBarAnim.reverse();
7 } else {
8 mQSBSearchBarAnim.cancel();
9 if (mEnableDropDownDropTargets) {
10 mQSBSearchBar.setTranslationY(0);
11 } else {
12 mQSBSearchBar.setAlpha( 0f ); //参数改为 0f;
13 }
14 }
15 mIsSearchBarHidden = false;
16 }
三、hotseat的修改
改完之后,我们会发现hotseat排列到右边去了,显的很不美观是不是?作为车载导航的launcher,我们肯定是希望hotseat能排布在屏幕的Bottom啊,没关系,我们来改一下:
首先,我们需要修改Hotseat.java
1 public Hotseat(Context context, AttributeSet attrs, int defStyle) {
2 super(context, attrs, defStyle);
3
4 TypedArray a = context.obtainStyledAttributes(attrs,
5 R.styleable.Hotseat, defStyle, 0);
6 mCellCountX = a.getInt(R.styleable.Hotseat_cellCountX, -1);
7 mCellCountY = a.getInt(R.styleable.Hotseat_cellCountY, -1);
8 mAllAppsButtonRank = context.getResources().getInteger(R.integer.hotseat_all_apps_index);
9 mIsLandscape = false;//context.getResources().getConfiguration().orientation ==
10 //Configuration.ORIENTATION_LANDSCAPE;
11 }
注意这里有一个大屏幕还是小屏幕的判断,这个是用来判断属于平板系统还是一般的手机系统。因为我系统是只会在横屏时使用,所以我直接设置成mIsLandscape为小屏幕,因为Hotseat里面很多获取熟悉都是区分大小屏幕。小屏幕的时候,我们使用竖向配置hotseat就可以得到相当于手机系统的hotseat效果,hotseat会显示在屏幕底下。
下面我们看看Hotseat的配置文件,Hotseat是属于workspace的,所以需要在workspace配置文件里面配置,打开launcher.xml就可以看到hotseat的配置,这个并不是所有launcher.xml文件都有hotseat属性,如果你的launcher要适配多个分辨率的机器,那么你就得在适合你机器的分辨率下的相应的目录下的launcher.xml下添加hotseat属性。这里需要将android:layout_height和android:layout_width的属性对调一下,然后将android:layout_gravity改为bottom
1 <include layout="@layout/hotseat"
2 android:id="@+id/hotseat"
3 android:layout_height="@dimen/button_bar_height_plus_padding"
4 android:layout_width="match_parent"
5 android:layout_gravity="bottom" />
改完这个还是不够的,运行的时候,你会发现hotseat图标都缩到一起去了,还有一个地方也需要修改,layout-land/hotseat.xml也是需要做一下配置改 动的
1 <com.launcherjellybean.android.Hotseat
2 xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:launcher="http://schemas.android.com/apk/res/com.launcherjellybean.android"
4 launcher:cellCountX="@integer/hotseat_cell_count"
5 launcher:cellCountY="1">
6 <com.launcherjellybean.android.CellLayout
7 android:id="@+id/layout"
8 android:layout_width="wrap_content"
9 android:layout_height="match_parent"
10 android:layout_gravity="center"
11 android:paddingTop="@dimen/button_bar_height_top_padding"
12 android:paddingBottom="@dimen/button_bar_height_bottom_padding"
13 android:paddingLeft="@dimen/button_bar_width_left_padding"
14 android:paddingRight="@dimen/button_bar_width_right_padding"
15
16 launcher:cellWidth="@dimen/hotseat_cell_width"
17 launcher:cellHeight="@dimen/hotseat_cell_height"
18 launcher:widthGap="@dimen/hotseat_width_gap"
19 launcher:heightGap="@dimen/hotseat_height_gap"
20 launcher:maxGap="@dimen/workspace_max_gap" />
21 </com.launcherjellybean.android.Hotseat>
其中 launcher:cellCountX 的值和 launcher:cellCountY 是需要对调的,你想想就知道为什么了
另外 android:layout_height 也需要从wrap_content变成match_parent,去查查他们的区别,你就知道为什么这么改了
光是这么改,也依然不够,原生桌面图标是4* 4的布局,如果把hotseat挪下来,就变成了5 *4的图标了,显然,太拥挤了,那么就需要修改桌面的行列数, 打开文件values/config.xml,修改以下2个字段
<integer name="cell_count_x">4integer>
<integer name="cell_count_y">3integer>
这里我将cell_count_y从4改成了3,从而让hotseat占据了第四行,运行发现除了hotseat那一行的图标,其余图标都排布的比较下面,这是什么原因呢,这是因为桌面图标的高度是自适应居中的,由于我们修改了配置为3行,那么桌面图标自然在上下都留出了相应的高度,以便让图标居中了,所以,我们要让桌面图标知道,最后一行是被hotseat给占据了,从而还需要修改launcher.xml这个文件
1 <com.launcherjellybean.android.Workspace
2 android:id="@+id/workspace"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:paddingLeft="@dimen/workspace_left_padding"
6 android:paddingRight="@dimen/workspace_right_padding"
7 android:paddingTop="0dp"
8 android:paddingBottom="60dp"
9 launcher:defaultScreen="1"
10 launcher:cellCountX="@integer/cell_count_x"
11 launcher:cellCountY="@integer/cell_count_y"
12 launcher:pageSpacing="@dimen/workspace_page_spacing"
13 launcher:scrollIndicatorPaddingLeft="@dimen/qsb_bar_height"
14 launcher:scrollIndicatorPaddingRight="@dimen/button_bar_height">
这里,我修改了android:paddingBottom 和 android:paddingTop这2个值,以让图标看起来不会那么奇怪,这样,已经成功了一大半了
四、去掉多余的2根竖线
我们修改完以上的东西,会发现还多了2根竖线,一根是google search bar留下的,另外一根是hotseat剩下的,放在2边很不美观,对吧,绝壁要去掉啊!!! 那么,这2根讨厌的竖线在哪呢,它们就藏在launcher.java里:
1 private View mQsbDivider;
2 private View mDockDivider;
我们找到和这2个变量有关的代码,全部予以屏蔽即可,比如hideDockDivider() 、showDockDivider()这些之类的,要坚决予以屏蔽,另外在WorkSpace.java里也发现了它们的身影:
1 void setFadeForOverScroll(float fade) {
2 if (!isScrollingIndicatorEnabled()) return;
3
4 mOverscrollFade = fade;
5 float reducedFade = 0.5f + 0.5f * (1 - fade);
6 final ViewGroup parent = (ViewGroup) getParent();
7 // final ImageView qsbDivider = (ImageView) (parent.findViewById(R.id.qsb_divider));
8 // final ImageView dockDivider = (ImageView) (parent.findViewById(R.id.dock_divider));
9 final View scrollIndicator = getScrollingIndicator();
10
11 cancelScrollingIndicatorAnimations();
12 //if (qsbDivider != null) qsbDivider.setAlpha(reducedFade);
13 //if (dockDivider != null) dockDivider.setAlpha(reducedFade);
14 scrollIndicator.setAlpha(1 - fade);
15 }
也跟我一起屏蔽它们就可以了,这样烦人的竖线就不会出现了,你也会做到和我在一开始展示的那样的效果。