Launcher研究之文件夹美化
作者:sonken , 2011-07-02
欢迎转载,并请注明作者以及出处!
Android原生桌面文件夹在这个张扬个性的时代,已经略显过时。所以,今天我们的主要目地就是将其改头换面,美化ING!
开始之前我们先看看Iphone文件夹的样式吧!

Android原生桌面文件夹在这个张扬个性的时代,已经略显过时。所以,今天我们的主要目地就是将其改头换面,美化ING!
开始之前我们先看看Iphone文件夹的样式吧!

1.材料准备
一张png格式的背景图(78*78),我们这里准备的图片是
一张png格式的背景图(78*78),我们这里准备的图片是

2.思路分析
简而言之:获取放入文件夹内item的图标(缩略图),并将其按照一定顺序绘制在我们之前准备好的背景图上,拖动完成之后显示该背景图。
对于Launcher桌面文件夹的创建过程不是很清楚的童鞋,可以参考以下本人对FolderIcon总结.
(1).android 的桌面文件夹主要包括LiveFolder(实时文件夹),UserFolder(用户文件夹)。LiveFolder主要包括创建桌面联系人文件夹、蓝牙文件夹等,UserFolder则通常是指在桌面上可以向其中添加应用程序(item)快捷方式的文件夹。这里需要修改的就当然是UserFolder。“对症下药”非常重要,在茫茫源码里找到自己需要修改的地方是成功关键的第一步。
(2).桌面文件夹的创建过程。
看得见的操作:1.长按桌面空白区域,弹出“添加到桌面”选项菜单,其中一项即为创建桌面文件夹。
2.单击“menu”按钮,其中“添加”项也可以完成同样的操作。
看不见的操作:1.开机启动,运行Luancher的过程中,若桌面上已经存在文件夹,创建并刷新屏幕。
2.当在Home界面创建桌面文件夹时,根据选择创建相应的文件夹,,注册该文件夹在数据库中的信息,屏幕刷新,在桌面上显示。
(3).源代码分析。以上创建过程的分析大部分是在源码Launcher,FolderIcon,UserFolder,UserFolderInfo的基础上总结。
3.桌面文件夹图标(Icon)该如何显示内部item的缩略图?
这里主要我把它分成两种情况来考虑,分别在文件夹关闭和打开状态下,拖动item到文件夹内时,桌面文件夹图标随之更新。当然也分别对应了不同的源代码FolderIcon和UserFolder。
以文件夹关闭状态下图标的更新为例。源码目录 packages/apps/Launcher2/FolderIcon.java;
简而言之:获取放入文件夹内item的图标(缩略图),并将其按照一定顺序绘制在我们之前准备好的背景图上,拖动完成之后显示该背景图。
对于Launcher桌面文件夹的创建过程不是很清楚的童鞋,可以参考以下本人对FolderIcon总结.
(1).android 的桌面文件夹主要包括LiveFolder(实时文件夹),UserFolder(用户文件夹)。LiveFolder主要包括创建桌面联系人文件夹、蓝牙文件夹等,UserFolder则通常是指在桌面上可以向其中添加应用程序(item)快捷方式的文件夹。这里需要修改的就当然是UserFolder。“对症下药”非常重要,在茫茫源码里找到自己需要修改的地方是成功关键的第一步。
(2).桌面文件夹的创建过程。
看得见的操作:1.长按桌面空白区域,弹出“添加到桌面”选项菜单,其中一项即为创建桌面文件夹。
2.单击“menu”按钮,其中“添加”项也可以完成同样的操作。
看不见的操作:1.开机启动,运行Luancher的过程中,若桌面上已经存在文件夹,创建并刷新屏幕。
2.当在Home界面创建桌面文件夹时,根据选择创建相应的文件夹,,注册该文件夹在数据库中的信息,屏幕刷新,在桌面上显示。
(3).源代码分析。以上创建过程的分析大部分是在源码Launcher,FolderIcon,UserFolder,UserFolderInfo的基础上总结。
3.桌面文件夹图标(Icon)该如何显示内部item的缩略图?
这里主要我把它分成两种情况来考虑,分别在文件夹关闭和打开状态下,拖动item到文件夹内时,桌面文件夹图标随之更新。当然也分别对应了不同的源代码FolderIcon和UserFolder。
以文件夹关闭状态下图标的更新为例。源码目录 packages/apps/Launcher2/FolderIcon.java;
public class FolderIcon extends BubbleTextView implements DropTarget {
private UserFolderInfo mInfo;
private Launcher mLauncher;
private Drawable mCloseIcon;
private Drawable mOpenIcon;
public FolderIcon(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FolderIcon(Context context) {
super(context);
}
/**
*原图是mCloseIcon,我们只需要将其替换成之前准备好的背景图,
*然后在该背景图上绘制内部item的缩略图即可。
*createFolderIconDrawable(folderInfo,launcher, icon)该方法是创建为我所需的图标。
*传值 (该文件夹的所有信息,Launcher,自己)
*/
static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
UserFolderInfo folderInfo) {
FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
final Resources resources = launcher.getResources();
Drawable d = icon.createFolderIconDrawable(folderInfo,launcher, icon); //modify by sonken
icon.mCloseIcon = d;
icon.mOpenIcon = resources.getDrawable(R.drawable.ic_launcher_folder_open);
icon.setCompoundDrawablesWithIntrinsicBounds(null, d, null, null);
icon.setText(folderInfo.title);
icon.setTag(folderInfo);
icon.setOnClickListener(launcher);
icon.mInfo = folderInfo;
icon.mLauncher = launcher;
return icon;
}
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo;
final int itemType = item.itemType;
return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT)
&& item.container != mInfo.id;
}
public Rect estimateDropLocation(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo, Rect recycle) {
return null;
}
//只有我们拖动着的item完全放到文件夹里的时候,再跟新图标不迟!
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
ShortcutInfo item;
if (dragInfo instanceof ApplicationInfo) {
// Came from all apps -- make a copy
item = ((ApplicationInfo)dragInfo).makeShortcut();
} else {
item = (ShortcutInfo)dragInfo;
}
mInfo.add(item);
LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, 0, 0);
//add by sonken
setCompoundDrawablesWithIntrinsicBounds(null, createFolderIconDrawable(mInfo, mLauncher, this), null, null);
}
public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
}
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
}
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
}
//add by sonken
private Drawable createFolderIconDrawable(UserFolderInfo folderInfo,
Launcher launcher, FolderIcon icon) {
// TODO Auto-generated method stub
UserFolderInfo info = folderInfo ;
Launcher content = launcher;
Drawable mdrawIcon = DrawInfo(info,content);
icon.mCloseIcon = mdrawIcon;
return icon.mCloseIcon;
}
//如何在背景图上绘制item的缩略图
private Drawable DrawInfo(UserFolderInfo sInfo, Launcher content) {
// TODO Auto-generated method stub
final Resources resource = content.getResources();
Bitmap background = BitmapFactory.decodeResource(resource, R.drawable.ic_launcher_folder);
Bitmap BGbmp = Bitmap.createScaledBitmap(background,(background.getWidth())*3/2,(background.getHeight())*3/2, false);
int count = sInfo.contents.size();
count = count > 4 ? 4 : count;
Canvas canvas = new Canvas(BGbmp); //将背景图作为画布
for(int i = 0; i < count; i++){
ShortcutInfo info = sInfo.contents.get(i); //获取item的信息
Bitmap orgbmp = info.getIcon(((LauncherApplication)content.getApplicationContext()).getIconCache()); //获取item的Icon
int width = orgbmp.getWidth();
int height = orgbmp.getHeight();
int newWidth =40;
int newHeight = 40;
float scaleW =((float)newWidth)/width ;
float scaleH =((float)newHeight)/height;
Matrix matrix = new Matrix();
matrix.postScale(scaleW, scaleH);
Bitmap thumbmp = Bitmap.createBitmap(orgbmp, 0, 0, width, height, matrix, true); //将item的Icon变小!!!---获取缩略图
//分别在背景图的不同位置,绘制该item的icon缩略图!!
if(i == 3)
canvas.drawBitmap(thumbmp, 55, 55, null);
if(i == 2)
canvas.drawBitmap(thumbmp, 10, 55, null);
if(i == 1)
canvas.drawBitmap(thumbmp, 55, 10, null);
if(i == 0)
canvas.drawBitmap(thumbmp, 10, 10, null);
canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
}
//将bitmap转为Drawable
@SuppressWarnings("deprecation")
BitmapDrawable mCloseIcon = new BitmapDrawable(BGbmp);
return mCloseIcon; //大功告成!
}
//add by sonken
}
以上仅仅只适用于文件夹关闭的状态下图标“美化“,但文件夹打开状态下的情况与其类似,这里不再赘述!
个人观点特拿来与各位分享,不足之处还请多多指教,谢谢!