Android平台自带的桌面文件夹非常简单,没有类似iPhone可以显示文件图标缩略图的功能,今天我们就来实现一个简单的美化文件夹功能。 从launcher的源代码我们中很容易可以找出需要修改的文件,主要修改FolderIcon.Java这个文件。
修改后的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
public class FolderIcon extends BubbleTextView implements DropTarget {
private UserFolderInfo mInfo;
private Launcher mLauncher;
private Drawable mCloseIcon;
private Drawable mOpenIcon;
// add by hmg for FolderIcon {
private IconCache mIconCache;
private static final int ICON_COUNT = 4; //可以显示的缩略图数
private static final int NUM_COL = 2; // 每行显示的个数
private static final int PADDING = 1; //内边距
private static final int MARGIN = 7; //外边距
// add by hmg for FolderIcon}
public FolderIcon(Context context, AttributeSet attrs) {
super(context, attrs);
mIconCache = ((LauncherApplication) mContext.getApplicationContext()).getIconCache();
}
public FolderIcon(Context context) {
super(context);
mIconCache = ((LauncherApplication) mContext.getApplicationContext()).getIconCache();
}
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 = resources.getDrawable(R.drawable.ic_launcher_folder);
// 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;
icon.updateFolderIcon(); //更新图标
folderInfo.setFolderIcon(icon); //设置FolderIcon
return icon;
}
// add by hmg25 for FolderIcon {
/**
* Author : hmg25 Version: 1.0 Description : 更新FolderIcon显示的文件缩略图
*/
public void updateFolderIcon() {
float x, y;
final Resources resources = mLauncher.getResources();
Bitmap closebmp = BitmapFactory.decodeResource(resources, R.drawable.icon_folder); //获取FolderIcon关闭时的背景图
Bitmap openbmp = BitmapFactory.decodeResource(resources, R.drawable.icon_folder_open); //获取FolderIcon打开时的背景图
int iconWidth = closebmp.getWidth(); //icon的宽度
int iconHeight = closebmp.getHeight();
Bitmap folderclose = Bitmap.createBitmap(iconWidth, iconHeight, Bitmap.Config.ARGB_8888);
Bitmap folderopen = Bitmap.createBitmap(iconWidth, iconHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(folderclose);
canvas.drawBitmap(closebmp, 0, 0, null); //绘制背景
Matrix matrix = new Matrix(); // 创建操作图片用的Matrix对象
float scaleWidth = (iconWidth - MARGIN * 2) / NUM_COL - 2 * PADDING;
//计算缩略图的宽(高与宽相同)
float scale = (scaleWidth / iconWidth); // 计算缩放比例
matrix.postScale(scale, scale); // 设置缩放比例
for (int i = 0; i < ICON_COUNT; i++) {
if (i < mInfo.contents.size()) {
x = MARGIN + PADDING * (2 * (i % NUM_COL) + 1) + scaleWidth* (i % NUM_COL);
y = MARGIN + PADDING * (2 * (i / NUM_COL) + 1) + scaleWidth* (i / NUM_COL);
ShortcutInfo scInfo = (ShortcutInfo) mInfo.contents.get(i);
Bitmap iconbmp = scInfo.getIcon(mIconCache); //获取缩略图标
Bitmap scalebmp = Bitmap.createBitmap(iconbmp, 0, 0, iconWidth, iconHeight, matrix, true);
canvas.drawBitmap(scalebmp, x, y, null);
}
}
mCloseIcon = new FastBitmapDrawable(folderclose); //将bitmap转换为Drawable
setCompoundDrawablesWithIntrinsicBounds(null, mCloseIcon, null, null);
canvas = new Canvas(folderopen);
canvas.drawBitmap(folderclose, 0, 0, null);
canvas.drawBitmap(openbmp, 0, 0, null);
mOpenIcon = new FastBitmapDrawable(folderopen); //绘制open图片
}
// add by hmg25 for FolderIcon
}
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;
}
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);
updateFolderIcon(); //拖拽放入时更新
}
public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) {
setCompoundDrawablesWithIntrinsicBounds(null, mOpenIcon, null, null);
}
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) {
setCompoundDrawablesWithIntrinsicBounds(null, mCloseIcon, null, null);
}
}
将文件拖拽进入文件夹时将响应FolderIcon中的onDrop事件,所以我们要添加updateFolderIcon();以上代码可以实现将图标拖拽进文件夹时实时更新缩略图显示,还没有对拖拽出文件夹时更新显示,所以还需要修改其他地方。跟踪代码可以看出拖拽离开文件夹时响应UserFolder中onDropCompleted方法,我们需要修改UserFolder.Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void onDropCompleted(View target, boolean success) {
if (success) {
ShortcutsAdapter adapter = (ShortcutsAdapter)mContent.getAdapter();
adapter.remove(mDragItem);
((UserFolderInfo)mInfo).mFolderIcon.updateFolderIcon(); //add by hmg25 拖拽离开时更新
}
}
ublic 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;
}
((ShortcutsAdapter)mContent.getAdapter()).add(item);
LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, 0, 0);
((UserFolderInfo)mInfo).mFolderIcon.updateFolderIcon();
//add by hmg25 将文件直接拖拽到打开的文件夹时更新
从以上代码可以看出为了传递FolderIcon对象,所以我们还需要为UserFolderInfo添加一个mFolderIcon成员,修改UserFolderInfo.java:
1
2
3
4
5
6
7
8
9
protected FolderIcon mFolderIcon = null; //add by hmg25 for Folder
//add by hmg25 for Folder {
void setFolderIcon(FolderIcon icon) {
mFolderIcon=icon;
}
//add by hmg25 for Folder}
1
2
3
4
5
6
7
8
//可以显示的缩略图数
private static final int ICON_COUNT = 4;
// 每行显示的个数
private static final int NUM_COL = 2;
//内边距
private static final int PADDING = 1;
//外边距
private static final int MARGIN = 7;