Android Launcher研究之文件夹美化

本文介绍了如何在Android中对用户文件夹进行美化,通过替换背景图和绘制内部item的缩略图,实现桌面文件夹的个性化。文章详细分析了创建桌面文件夹的过程,提供了在FolderIcon和UserFolder类中修改代码的方法,展示了在文件夹关闭和打开状态下更新图标的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Launcher研究之文件夹美化

    作者:sonken   , 2011-07-02
   欢迎转载,并请注明作者以及出处!


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






   


















     1.材料准备
     一张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;
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
}



以上仅仅只适用于文件夹关闭的状态下图标“美化“,但文件夹打开状态下的情况与其类似,这里不再赘述!
个人观点特拿来与各位分享,不足之处还请多多指教,谢谢!
Dr. Folder 是一款界面友好、功能强大、简单易用的文件夹美化工具,只需简单的点击几次,即可快速地更改任意文件夹的标准图标,使其变成生动活泼、令人羡慕的漂亮文件夹! 优点: - 组织有序 - 使用“优先级”图标确定任务的优先级或指示流程进度 - 节省查找文件的时间 - 只需点击一下即可将文件夹整理好 - 保护有价值的信息免遭意外删除 - 高亮显示不能删除的重要文件夹 - 个性化您的工作区 - 使您的文件夹与其他文件夹不同,在一台计算机或局域网上与其他用户共享 主要特点: - Dr. Folder 可更改网络文件夹的图标,所以您可自定义你的局域网 - Dr. Folder 包含在办公室工作时的其他图标 - Dr. Folder 允许您以最简单的方式更改文件夹图标(只需点击一下鼠标) - Dr. Folder 还有两个用于更改文件夹图标的选项:“使自定义文件夹可分发”(便携式)和“将选择图标应用于所有子文件夹” - Dr. Folder 可按优先级(高、正常、低)、工作完成度(完成、半完成、计划)、工作状态(批准、拒绝、待定)以及包含的信息类型标记文件夹(工作文件、重要文件、临时文件、私人文件)。 - Dr. Folder 可将文件夹的颜色更改为正常、深色和浅色状态 - Dr. Folder 可从文件夹的弹出菜单中更改文件夹的图标。您甚至不需要运行该程序就可更改文件夹图标! - Dr. Folder 的弹出菜单包含方便的类别子菜单。 - Dr. Folder 还包含一个用户图标选项卡,您可在其中无限量的添加您喜欢的图标并使用它们标记文件夹。这很简单! Dr. Folder 允许你: - 只需点击鼠标,即可将不同的图标应用于各个文件 - 从系统上下文菜单轻松更改文件夹图标 - 替换由 Windows 用于显示计算机上每个文件夹的系统定义的标准文件夹图标 - 在您的计算机上搜索图标 - 将图标复制到当前文件夹,使您的文件夹图标独立于图标源文件(允许您将自定义文件夹移动或复制到任何地方甚至另一台计算机!您的文件夹将与您指定的完全一致) - 重建系统图标缓存以修复不正确的图标图像 - 将您喜欢的图标添加到用户图标列表以更快地访问它们 - 从 PNG、BMP、JPG 或 GIF 文件转换图标 需要Net4.0,自动注册,便携单文件,Win10闪退请用兼容模式运行
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值