Android源码下的系统定制

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

在源码路径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" />
		<favorite
			launcher: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
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值