HoloEveryWhere笔记

王楚青
2023-12-01

简介

HoloEveryWhere 是一套 Android 开发库,提供了全套 Holo Style 控件,它的外观与功能和标准 Holo Style 控件基本相同,但是它可以运行在低于 4.0 版本的 Android 系统上。

除此之外,还必须提到的另一个库——同时也是 HoloEveryWhere 所必须依赖的库: ActionBarSherlock 。它提供了 Android 4.x 起提供的最重要的UI控件: ActionBar 。

不过两个库在某些方面(如 Fragment )有重复之处,所以使用时要小心,如果不想使用 Holo 控件,只使用 ActionBar 的话,就只使用 ActionBarSherlock 。否则的话,除了 ActionBar ,其它的都要使用 HoloEveryWhere 提供的版本,以免发生各种意想不到的情况。

下载

安装的第一步就是先下载源码,按文档所说:

git clone --branch stable git://github.com/Prototik/HoloEverywhere.git HoloEverywhere
cd HoloEverywhere
git submodule update --init --recursive

注意,如果以前用过旧版想要升级,最好也删除重新下载一次,以免有妖蛾子问题发生。

之后的操作如文档所说,但往往还不够。以下以作本文时的版本为例。

安装 ActionBarSherlock

首先是安装 ActionBarSherlock ,但是因为 HoloEveryWhere 使用了一个不同的android-support-v4.jar 库文件,为了保持一致(否则编译时会出错),需要把 ActionBarSherlock 里用的库文件改为 HoloEveryWhere 用的版本:

rm contrib/ActionBarSherlock/library/libs/android-support-v4.jar
ln -s support-library/android-support-v4-r12.jar contrib/ActionBarSherlock/library/libs/android-support-v4.jar

如果想试试看 ActionBarSherlock 的 Demos ,同样也需要把 Demos 里的 support 库这样改。你自己的应用也一样要使用这个版本的 support 库。

然后才可以安装 ActionBarSherlock ,不过因为它缺少某些文件,不能直接 Import ,需要用这样的方式来把它加入到 Eclipse 里:

New|Other...|Android Project from Exiting Code

路径是:

contrib/ActionBarSherlock/library

另外,这样装好的项目名叫 library ,建议改一下。

安装HoloEveryWhere

之后是安装 HoloEveryWhere ,这个就可以直接用 Import 方式把它加入到 Eclipse 里了 。路径是:

HoloEveryWhere/library

不过这样直接抓到 Eclipse 里会有一堆错误,解决的方法是:

删除项目下面的 pom.xml文件。

为了在应用中正常使用 SharedPreferences ,还需要用同样的方法安装一个 Addon :

addons/preferences

如缺少这个,虽然同样可以使用系统库的 SharedPreferences 编译,但运行时将会出错: preference framework not found什么的。

如果要跑 HoloEveryWhere 的那个 Demo ,还需要安装另一个Addon:

addons/sildingmenu

使用

ActionBarSherlock 和 HoloEveryWhere 的使用方法详见各自的 Demo 程序。不过使用中有些注意事项值得记录一下(主要是 HoloEveryWhere ):

在使用这个两个库之前,需要在应用的:

Project | Properties | Android | Library

里把相应的库添加进去。如前面所说,如果只使用 ActionBarSherlock ,就只把它加入进去,如果同时还使用了 HoloEveryWhere ,就不必加 ActionBarSherlock 了,因为已经包含在 HoloEveryWhere 里了。不过上面提到的 Addons 如果用到的话,倒是需要在这里加上的。

在创建一个使用 HoloEveryWhere 的应用时,首先必须创建一个 Application :

public class YourtApplication extends Application {
    private static final String PACKAGE = YourApplication.class.getPackage().getName();
    static {
        HoloEverywhere.DEBUG = true;
        HoloEverywhere.PREFERENCE_IMPL = PreferenceImpl.JSON;

        LayoutInflater.registerPackage(PACKAGE + ".widget");

        ThemeManager.setDefaultTheme(ThemeManager.MIXED);

        // Android 2.* incorrect process FULLSCREEN flag when we are modify
        // DecorView of Window. This hack using HoloEverywhere Slider
        if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
            ThemeManager.modify(ThemeManager.FULLSCREEN);
        }
    }
}

这段代码来自官方 Demo 。注意,其中的基类 Application 不是系统库的那个,而是 HoloEveryWhere 的。这里主要做一些初始化工作。

然后需要修改 AndroidManifest.xml ,将其中的 Application Attributes里的 Name设置为这个 Application。

另外,还要把Application Attribute里的Theme属性清空,因为Holo只支持它自己的主题,不能使用默认的 @style/AppTheme 主题。

之后就可以在应用里正常使用各种系统标准UI控件,只是在程序里使用相应的类时,要用 HoloEveryWhere 的版本。

其它注意事项

如果在 ActionBar 里使用了 Tab ,那么传统的菜单就不能用了,会导致FC。

当然,如果只使用 ActionBarSherlock ,不使用 HoloEveryWhere 的话,还是可以使用 ActionBarSherlock 的菜单的。但是如果使用 HoloEveryWhere 的话,就完全没法使用菜单了,虽然在 4.0 以上的系统中使用 ActionBarSherlock 的菜单还是可以运行的,但是在 2.3 及以下的系统中按菜单键将闪退。

所以在 HoloEveryWhere 应用中,最好是使用别的方式切换 Activity ,或者索性就用 Fragment 。当然还有一个选择是用那个 SlidingMenu 的 Addon 。

或者不要把Tab放到 ActionBar 里,但这样就会占用两条屏幕空间——最顶上是一行 ActionBar ,第二行是 Tab ,以下才是内容部分。

还有 Preferece 页面有一点需要注意,直接使用默认的 xml 文件,在 HoloEveryWhere 的 PreferenceFragment 里使用会有一个问题:能够显示 Preference 的格式,但是所有文字内容都不显示,并且点击 list 项目会FC,需要作一点修改:

把 XML 文件的 xmlns 从“http://schemas.android.com/apk/res/android”改成:“http://schemas.android.com/apk/res-auto”

至于修改界面的主题,可以通过 ThemeManager 实现:

ThemeManager.setDefaultTheme(ThemeManager.MIXED);
ThemeManager.restart(activity, false);

不过有时上面这个 restart 会失灵,从 log 上看是 holo 内部发生异常,而且用这种方法重启 activity 有个问题就是会丢失当前的 activity 状态。所以我又用了另外一种方法来重启 activity :

Intent intent = getIntent();
intent.putExtra(...);  //  保存状态,之后在onCreate里恢复
finish();
startActivity(intent);

这样一般就没问题了——当然,前提是记得把AndroidManifest.xml里的Application Theme属性清空,否则即使这里设置了还是要出错的。

 类似资料: