中易网

如何实现workspace加载所有应用 android

答案:1  悬赏:30  
解决时间 2021-02-07 03:26
如何实现workspace加载所有应用 android
最佳答案
最近工作都在修改Launcher,所以打算把分析源码和修改源码的过程记录下来,最近会写一些关于Launcher的分析和修改博文。因为我是修改4.0.3的Launcher,所以后面文章里面的Launcher都是基于Android4.0.3的Launcher2修改。Launcher源码比较多,而且里面应用了很多设计模式,要把它分析清楚要花不少精力,网上也有一些零碎的分析文章,不过关于修改的文章不多。所以打算写一些分析和修改Launcher结合的文章。

今天主要是分析修改Launcher的默认界面如何配置和修改。Launcher修改是最近才开始,下面两张图片是最近修改后的结果。因为程序是用于车载导航仪的,所以界面和一般的手机界面差别较大。改动也比较大,不过对于Launcher的分析修改都是通用的。

这是基于Android4.0.3修改后的Launcher界面,因为程序是用在汽车导航上,所以图标做了放大操作。删除了一些不需要的东西。
下面针对界面修改的地方做分析。
1、界面默认配置文件
机器刚升级的时候,Launcher的界面是默认读取一个xml配置文件,完成配置工作。这个配置文件在Launcher目录下,
路径是:\Launcher\res\xml\default_workspace.xml 。这个XML文件就是刚升级,Launcher第一次显示的时候,会读取的配置文件。
default_workspace。xml里面可以配置APP快捷方式、Widget、Search搜索栏等。下面就常用的这几个属性进行解析:
快捷方式说明
launcher:className="com.apical.radio.radioMainActivity" //该应用的类,点击图标时,需要启动的类
launcher:packageName="com.apical.radio" //该应用的包名
launcher:screen="1" //第1屏,0-4屏共5屏
launcher:x="0" //图标X位置,左上角第一个为0,向左递增,0-4共5个
l0auncher:y="0" //图标Y位置,左上角第一个为0,向下递增,0-2共3个
/>
复制代码
Launcher默认是有5个分屏,不过这个可以配置。同样,每行每列有多少图标也是可以配置的,这个在后面会说在哪里可以修改。这里按我修改的是3行5列的界面排布(对应上面的效果图)。一般配置APP的快捷方式,使用上面的属性标签就可以。
//桌面Widget的标签
//在y方向上所占格数
复制代码
桌面Widget跟桌面快捷方式属性类型,不过这里需要注意launcher:spanX和launcher:spanY 这两个属性是说明Widget多大的,这个和Widget的最小宽高配置有关。我们在编写桌面Widget的时候,需要在XML配置文件里面指定Widget最小的宽和高,一般最小宽高计算公式是(minWidth = 72*占用格数-2) 计算出来,最小高度也是一样。(上面那个模拟时钟是MIUI的时钟) minWidth = 72*占用格数-2里面的占用格数就是上面launcher:spanX和launcher:spanY配置的数目。针对上面的效果图,就是占用了3个横向的格子,2个竖向的格子。minWidth应该等于214。
launcher:screen="1" //第2屏
launcher:x="0" //图标X位置
launcher:y="1"/> //图标Y位置
复制代码
这个是搜索栏的配置,因为我这里不需要用到搜索栏,所以把它去掉了,如果需要配置可以使用上面的属性标签。 至于文件夹,在4.0的Launcher里面是支持的,分析加载函数里面,可以找到解析文件夹标签的方法。上面界面默认配置就是通过使用上面的标签修改default_workspace.xml配置的。下面列出default_workspace支持的标签和属性:
//default_workspace.xml中,支持的标签有:
favorite:应用程序快捷方式。
shortcut:链接,如网址,本地磁盘路径等。
search:搜索框。
clock:桌面上的钟表Widget

//支持的属性有:
launcher:title:图标下面的文字,目前只支持引用,不能直接书写字符串;
launcher:icon:图标引用;
launcher:uri:链接地址,链接网址用的,使用shortcut标签就可以定义一个超链接,打开某个网址。
launcher:packageName:应用程序的包名;
launcher:className:应用程序的启动类名;
launcher:screen:图标所在的屏幕编号;
launcher:x:图标在横向排列上的序号;
launcher:y:图标在纵向排列上的序号;
复制代码
Launcher里面负责解析default_workspace.xml文件的方法是 LauncherProvider.java里面的loadFavorites方法。 2、LauncherProvider.java的loadFavorites分析:
//传入default_workspace文件的资源ID和数据库实力,把xml里面数据解析,保存到Launcher数据库。返回总共解析了多少个标签。
private int loadFavorites(SQLiteDatabase db, int workspaceResourceId) {

//.........
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT)
{

if (type != XmlPullParser.START_TAG) {
continue;
}

boolean added = false;
final String name = parser.getName();

TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.Favorite);

long container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
if (a.hasValue(R.styleable.Favorite_container)) {
container = Long.valueOf(a.getString(R.styleable.Favorite_container));
}

String screen = a.getString(R.styleable.Favorite_screen);
String x = a.getString(R.styleable.Favorite_x);
String y = a.getString(R.styleable.Favorite_y);

// If we are adding to the hotseat, the screen is used as the position in the
// hotseat. This screen can't be at position 0 because AllApps is in the
// zeroth position.
if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT
&& Integer.valueOf(screen) == allAppsButtonRank) {
throw new RuntimeException("Invalid screen position for hotseat item");
}

values.clear();
values.put(LauncherSettings.Favorites.CONTAINER, container);
values.put(LauncherSettings.Favorites.SCREEN, screen);
values.put(LauncherSettings.Favorites.CELLX, x);
values.put(LauncherSettings.Favorites.CELLY, y);

//解析xml里面的标签,从这里可以找到支持的标签类型和相关属性参数。
if (TAG_FAVORITE.equals(name)) {
long id = addAppShortcut(db, values, a, packageManager, intent);
added = id >= 0;
} else if (TAG_SEARCH.equals(name)) {
added = addSearchWidget(db, values);
} else if (TAG_CLOCK.equals(name)) {
added = addClockWidget(db, values);
} else if (TAG_APPWIDGET.equals(name)) {
added = addAppWidget(parser, attrs, type, db, values, a, packageManager);
} else if (TAG_SHORTCUT.equals(name)) {
long id = addUriShortcut(db, values, a);
added = id >= 0;
} else if (TAG_FOLDER.equals(name))
{
//.........

//folder属性里面的参数要多于2个,才能形成文件夹。
if (folderItems.size() < 2 && folderId >= 0) {
// We just delete the folder and any items that made it
deleteId(db, folderId);
if (folderItems.size() > 0) {
deleteId(db, folderItems.get(0));
}
added = false;
}
}
if (added) i++;
a.recycle();
}
//.........
return i;
}
复制代码
其实就是一个分析XML和写入数据库的过程,LauncherProvider.java是整个Launcher的数据来源,十分重要,后面我再具体分析数据加载和适配显示方面的逻辑。
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
珠江国际花园我想知道这个在什么地方
谁有初中数学网的账号?www.czsx.com.cn求借
我女儿是1986年4月27日出生,请问阳历是几月几
昌教市场怎么去啊,有知道地址的么
扎兰艺校附属幼儿园地址在什么地方,想过去办
买不到动车票。。。怎么办
万用表的问题
逆转录酶具有3'→5'核酸外切酶活性
安阳永兴钢铁有限公司我想知道这个在什么地方
食安主题博览会上来了很多商家,每一家的商家
为什么我家鹦鹉下了两次蛋都不孵,没有小鸟?
歌词里有“失去你的我”
螃蟹地我想知道这个在什么地方
使用Tp-link的软AP共享网络,很不稳定,该如何
码上素食在哪里啊,我有事要去这个地方
推荐资讯
用H2O2制氧气的发生装置为_________型,用KMn
乌龟能吃火腿肠嘛?
操作系统vivox6 yun os.3.1好吗?
lingo这个错误报告index variables may not s
QQ9位靓号评估价格应该是多少?QQ号100455955
不锈钢304钢管价格是按重量还是按长度算
是不是晨昏线通过北极点就是2分日,为什么,
我终于知道科比为什么有这么多粉丝了
昆山市周庄自立包装厂地址在哪,我要去那里办
桃源招待所地址在哪,我要去那里办事
3D问题,VRayDisplacementMod在哪呢,没找到
红光镇佳苑综合市场(东北门)地址有知道的么?
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?