Android源码下的系统定制

来源:互联网 发布:mac的airplay在哪里 编辑:程序博客网 时间:2024/05/01 13:50

一 。如何隐藏屏幕下方的虚拟按键栏?

在源码路径framework/base/core/res/res/values/config.xml文件中,有一个标签<bool name=”config_showNavigationBar”>true<bool>,将其值设为true就可以看到虚拟按钮,设为false则会隐藏;

二。状态栏的定制

    在源码的frameworks/base/packages/SystemUI路径下,这是一个完整的android工程,系统UI包括虚拟按键,状态栏的实现都在这个工程中,可以修改;

    比如隐藏状态栏的电量图标,找到BatteryController.java类,可以在里面将相关的view隐藏,可参考文章Android源码开发之状态栏;

三。系统的裁剪

    在源码路径device\softwinner\wing-common\preinstallapk以及googleservice下,可以自行删减无用的应用和服务,具体路径随具体情况有所变化;假如想要预装软件,也可以将apk放入preinstallapk目录下,经过编译后,在out\...\preinstallapk目录下会出现同样的文件,就可以实现软件的预装;


四。桌面背景的修改

在源码路径下frameworks\base\core\res\res下的drawable文件夹中default_wallpaper即为默认墙纸,可以在不同分辨率的文件夹中进行替换来修改;这种背景图片会成为桌面所有屏幕的共同背景,比如桌面有5个屏幕,那么5个屏幕所显示出的所有画面拼接起来才会形成完整的墙纸图片,而且可以通过设置墙纸来进行修改;

此外,还可以在系统应用Launcher中,通过修改launcher.xml布局文件的背景来实现一个不可修改的背景,比如我之前所实现的桌面,需要一个类似窗框的背景,即在桌面四周有一周的黑边,见下图:


                                                                       

那么就可以采用这种方法。


五。Launch定制

Android4.2中的launcher。xml源码如下:

<FrameLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:launcher="http://schemas.android.com/apk/res/com.test.launcher"    android:id="@+id/launcher"    android:layout_width="match_parent"    android:layout_height="match_parent">    <com.test.launcher2.DragLayer        xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:launcher="http://schemas.android.com/apk/res/com.test.launcher"        android:id="@+id/drag_layer"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:fitsSystemWindows="true">        <!-- Keep these behind the workspace so that they are not visible when             we go into AllApps -->        <include            android:id="@+id/dock_divider"            layout="@layout/workspace_divider"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginBottom="@dimen/button_bar_height_plus_padding"            android:layout_gravity="bottom|center_horizontal" />        <include            android:id="@+id/paged_view_indicator"            layout="@layout/scroll_indicator"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="bottom"            android:layout_marginBottom="@dimen/button_bar_height_plus_padding" />        <!-- The workspace contains 5 screens of cells -->        <com.test.launcher2.Workspace            android:id="@+id/workspace"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:paddingLeft="@dimen/workspace_left_padding"            android:paddingRight="@dimen/workspace_right_padding"            android:paddingTop="@dimen/workspace_top_padding"            android:paddingBottom="@dimen/workspace_bottom_padding"            launcher:defaultScreen="2"            launcher:cellCountX="@integer/cell_count_x"            launcher:cellCountY="@integer/cell_count_y"            launcher:pageSpacing="@dimen/workspace_page_spacing"            launcher:scrollIndicatorPaddingLeft="@dimen/workspace_divider_padding_left"            launcher:scrollIndicatorPaddingRight="@dimen/workspace_divider_padding_right">            <include android:id="@+id/cell1" layout="@layout/workspace_screen" />            <include android:id="@+id/cell2" layout="@layout/workspace_screen" />            <include android:id="@+id/cell3" layout="@layout/workspace_screen" />            <include android:id="@+id/cell4" layout="@layout/workspace_screen" />            <include android:id="@+id/cell5" layout="@layout/workspace_screen" />        </com.test.launcher2.Workspace>        <include layout="@layout/hotseat"            android:id="@+id/hotseat"            android:layout_width="match_parent"            android:layout_height="@dimen/button_bar_height_plus_padding"            android:layout_gravity="bottom" />        <include            android:id="@+id/qsb_bar"            layout="@layout/qsb_bar" />        <!-- The Workspace cling must appear under the AppsCustomizePagedView below to ensure             that it is still visible during the transition to AllApps and doesn't overlay on             top of that view. -->        <include layout="@layout/workspace_cling"            android:id="@+id/workspace_cling"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:visibility="gone" />        <include layout="@layout/folder_cling"            android:id="@+id/folder_cling"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:visibility="gone" />        <com.test.launcher2.DrawableStateProxyView            android:id="@+id/voice_button_proxy"            android:layout_width="80dp"            android:layout_height="@dimen/qsb_bar_height"            android:layout_marginRight="@dimen/qsb_voice_proxy_padding_right"            android:layout_gravity="top|right"            android:clickable="true"            android:onClick="onClickVoiceButton"            android:importantForAccessibility="no"            launcher:sourceViewId="@+id/voice_button" />        <include layout="@layout/apps_customize_pane"            android:id="@+id/apps_customize_pane"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:visibility="invisible" />    </com.test.launcher2.DragLayer></FrameLayout>

1. view介绍

可以通过给FrameLayout设置background属性来设置背景;

DragLayer和WorkSpace都是FrameLayout的直接或间接子类;

dock_divider就是主屏幕workspace与底座hotseat之间的分隔线;

paged_view_indicator就是屏幕序号指示,和dock_divider重合;

workspace就是主屏幕view,桌面上的快捷方式,文件夹,widget等都是放在它里面,可以看到它里面包裹了5个workspace_screen,每一个都由CellLayout组成,代码桌面的5个屏,你可以通过增删来修改屏幕数量;

hotseat就是底座;

qsb_bar就是workspace上方的谷歌搜索栏以及长按后会出现的删除按钮;

workspace_cling和folder_cling是第一次启动桌面时,会出现的提示;

apps_customize_pane就是所有应用列表界面,点击home键之后它才会出现遮挡住workspace;

2. workspace

defaultScreen指定默认屏幕为第几个;

CellCountX为横向格栏个数,CellCountY为纵向格栏个数,这2个属性将真个workspace主屏幕分为若干个小方格,每一个快捷方式,文件夹,widget都通过指定位置放置在特定的小方格中;

workspace中实际容纳图标的是cellLayout,而hotseat中同样是由cellLayout作为最终盛放容器,所以它们在处理逻辑上是一致的,通过是否hotseat来实现特殊化;

3.hotseat 

hotseat背景可以通过设置background属性来实现,其高度也可以任意控制;

Android4.2的Launcher的hotseat.xml源码如下:

<com.test.launcher2.Hotseat    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:launcher="http://schemas.android.com/apk/res/com.test.launcher"    launcher:cellCountX="@integer/hotseat_cell_count"    launcher:cellCountY="1">    <com.test.launcher2.CellLayout        android:id="@+id/layout"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:layout_gravity="center"        android:paddingTop="@dimen/button_bar_height_top_padding"        android:paddingBottom="@dimen/button_bar_height_bottom_padding"        android:paddingLeft="@dimen/button_bar_width_left_padding"        android:paddingRight="@dimen/button_bar_width_right_padding"        launcher:cellWidth="@dimen/hotseat_cell_width"        launcher:cellHeight="@dimen/hotseat_cell_height"        launcher:widthGap="@dimen/hotseat_width_gap"        launcher:heightGap="@dimen/hotseat_height_gap"        launcher:maxGap="@dimen/hotseat_width_gap" /></com.test.launcher2.Hotseat>

(1)cellWidth和cellHeight分别控制图标的宽度和高度;

如果想要修改hotseat中图标的大小,光靠这2个属性恐怕还不行;在CellLayout.java中有个变量mHotseatScale,它代表hotseat内图标的缩放量,只有这3个量一起,才能达到修改hotseat内图标大小的最佳效果;

(2)无论是workspace还是hotseat内的一般图标的显示,都使用的是BubbleTextView控件,它继承于TextView;

通过将图片作为背景显示在文字上方的方式(TextView的setCompoundDrawables系列方法),来实现我们在桌面上看到的效果;

而hotseat中的图标是没有文字显示的,它是通过在CellLayout.java中的addViewToCellLayout()方法中设置字体颜色为透明来实现,但这种实现方法实际上文字仍然占用空间,只是我们看不到而已,同样可以通过设置文字大小为0来实现效果;


假如你要将hotseat内的图标放大,会发现图片可能显示不完整,那是因为看不见的透明文字也随之被放大并占用了空间,这时可以通过修改文字和图片的位置关系,设置文字大小,设置padding值来进行调整;

(3)all_apps_button也就是所有应用列表按钮,是在HotSeat.java中动态加载的,它也是一个BubbleTextView,它的位置可以通过config.xml文件中的hotseat_all_apps_index属性来设置,默认都是居于中间;

在Launcher.java中有一个onClickAllAppsButton()方法,这个按钮最终触发的就是这个方法;

(4)hotseat中的默认图标设置是在xml文件夹里的default_workspace.xml里面,一个典型的andrid4.2源码实例如下:

<favorites xmlns:launcher="http://schemas.android.com/apk/res/com.test.launcher">    <!-- Far-left screen [0] -->    <!-- Left screen [1] -->    <appwidget        launcher:packageName="com.android.settings"        launcher:className="com.android.settings.widget.SettingsAppWidgetProvider"        launcher:screen="1"        launcher:x="2"        launcher:y="1"        launcher:spanX="4"        launcher:spanY="1" />    <!-- Middle screen [2] -->    <!-- Right screen [3] -->    <!-- Far-right screen [4] -->    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->        <favorite        launcher:packageName="com.google.android.music"        launcher:className="com.android.music.activitymanagement.TopLevelActivity"        launcher:container="-101"        launcher:screen="1"        launcher:x="1"        launcher:y="0" />    <favorite        launcher:packageName="com.android.gallery3d"        launcher:className="com.android.gallery3d.app.Gallery"        launcher:container="-101"        launcher:screen="2"        launcher:x="2"        launcher:y="0" />    <favorite        launcher:packageName="com.android.gallery3d"        launcher:className="com.android.camera.CameraLauncher"        launcher:container="-101"        launcher:screen="4"        launcher:x="4"        launcher:y="0" />    <favorite        launcher:packageName="com.android.settings"        launcher:className="com.android.settings.Settings"        launcher:container="-101"        launcher:screen="5"        launcher:x="5"        launcher:y="0" />    <favorite      launcher:packageName="com.android.browser"      launcher:className="com.android.browser.BrowserActivity"      launcher:container="-101"      launcher:screen="6"      launcher:x="6"      launcher:y="0" />            <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->    <folder        launcher:title="@string/naming_is_Google"        launcher:container="-101"        launcher:screen="0"        launcher:x="0"        launcher:y="0" >        <favorite            launcher:className="com.google.android.gm.ConversationListActivityGmail"            launcher:packageName="com.google.android.gm" />        <favorite            launcher:className="com.google.android.apps.plus.phone.HomeActivity"            launcher:packageName="com.google.android.apps.plus" />        <favorite            launcher:className="com.google.android.maps.MapsActivity"            launcher:packageName="com.google.android.apps.maps" />        <favorite            launcher:className="com.android.music.activitymanagement.TopLevelActivity"            launcher:packageName="com.google.android.music" />        <favorite            launcher:className="com.google.android.youtube.videos.EntryPoint"            launcher:packageName="com.google.android.videos" />        <favorite            launcher:className="com.google.apps.dots.android.app.activity.CurrentsStartActivity"            launcher:packageName="com.google.android.apps.magazines" />        <favorite            launcher:className="com.google.android.apps.books.app.BooksActivity"            launcher:packageName="com.google.android.apps.books" />        <favorite            launcher:className="com.google.android.youtube.app.honeycomb.Shell$HomeActivity"            launcher:packageName="com.google.android.youtube" />        <favorite            launcher:className="com.google.android.talk.SigningInActivity"            launcher:packageName="com.google.android.talk" />        <favorite            launcher:className="com.android.calendar.AllInOneActivity"            launcher:packageName="com.google.android.calendar" />        <favorite            launcher:className="com.google.android.apps.chrome.Main"            launcher:packageName="com.android.chrome" /><favoritelauncher:packageName="com.android.vending"launcher:className="com.android.vending.AssetBrowserActivity"/>    </folder>        </favorites>

container为-101指的是hotseat,由此可以看到默认的hotseat布局是怎么样的;

有一篇关于这方面的博客写的非常好,Android Launcher分析和修改,强烈推荐。

六。关于Widget

widget就是桌面小部件;

在本次开发中,有一个桌面模拟时钟的需求,我根据AnalogClock的源码自己实现了一个模拟时钟,结果发现怎么样也没办法显示出来,后来在论坛上通过一位大仙的指导,才醍醐灌顶:widget里面所能使用的view是非常有限的,具体支持的view可参看sdk,明显它是不能放置自定义控件的;


不过后来我发现系统提供的AnalogClock模拟时钟其实是支持定制的,我们可以指定自己的表盘,指针等,而且它是被widget支持的,所以最后用这个方法很简单就实现了需求;

但是后来也在网上发现一篇文章,表示在源码环境下我们是有办法让任意的view都可以被widget所支持的,具体可参考这篇文章:Android之widget添加自定义控件介绍



0 0
原创粉丝点击