这篇,将记录如何将壁纸添加到桌面,以及Workspace如何处理滑动的时候,壁纸的滑动。 壁纸的添加,也是调用系统自带的,用如下方式调用:
//调用系统自带壁纸选择功能,ACTION_SET_WALLPAPER为选择的时候使用的过滤条件 Intent chooseIntent = new Intent(Intent.ACTION_SET_WALLPAPER); //启动系统选择应用 Intent intent = new Intent(Intent.ACTION_CHOOSER); intent.putExtra(Intent.EXTRA_INTENT, chooseIntent); intent.putExtra(Intent.EXTRA_TITLE, "选择壁纸"); startActivity(intent);这样就会列出所有Action含有android.intent.action.SET_WALLPAPER的应用。当然,上面的代码也可以直接简写为:
Intent chooseIntent = new Intent(Intent.ACTION_SET_WALLPAPER); startActivity(Intent.createChooser(chooseIntent, "选择壁纸"));但是,按照常见的,应该是startActivityForResult来启动,然后在onActivityResult中来获取返回后的壁纸。但是,选择壁纸后,并不是通过这种方式获取选择的壁纸的,那么我们如何获取选择的壁纸呢? 其实,当我们选择了一张壁纸后,系统会发出一个Broadcast,同时将选择的壁纸,缓存在整个应用程序的上下文中,这样,其实就是由于壁纸,不仅可以在桌面上更换,也可以在图片显示应用中更换,所以,其使用Broadcast机制来通知壁纸已经更换。我们需要实现一个BroadcastReciever来监听壁纸的选择:
/** * * 当别的应用程序改变了壁纸后,这里定义一个BroadcastReceiver来接受通知 * */ class WallpaperIntentReceiver extends BroadcastReceiver{ private Application application; //WeakReference使得WallpaperIntentReceiver不会因为Launcher的引用而被推迟注销掉 private WeakReference在这个BroadcastReciever中,直接通过Application.getWallpaper();获取最新的壁纸,那么有了BroadcastReciever,我们怎么知道这个Reciever是接收壁纸更换的Broadcast的呢?所以,我们需要注册它:rLauncher; public WallpaperIntentReceiver(Application application, UorderLauncher launcher) { this.application = application; this.rLauncher = new WeakReference (launcher); } public void setLauncher(UorderLauncher l){ this.rLauncher = new WeakReference (l); } @Override public void onReceive(Context context, Intent intent) { Log.v(TAG, "更换了壁纸"); /** * 从ApplicationContext获取壁纸 */ final Drawable lDrawable = application.getWallpaper(); if(lDrawable instanceof BitmapDrawable){ Log.v(TAG, "壁纸是BitmapDrawable类型的"); mWallpaper = ((BitmapDrawable)lDrawable).getBitmap(); }else{ throw new IllegalStateException("The wallpaper must be a BitmapDrawable object"); } /** * 如果此时Launcher是活动的,未被锁定,则加载新的Wallpaper */ if(rLauncher != null){ final UorderLauncher launcher = rLauncher.get(); if(launcher != null){ launcher.loadWallpaper(); } } } }
private void registerIntentReceivers(){ if(mWallpaperReceiver == null){ mWallpaperReceiver = new WallpaperIntentReceiver(getApplication(), this); /** * 注册的时候,指定IntentFilter,这样改BroadcastReciver就是接收壁纸更换的Broadcast的了 */ IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED); getApplication().registerReceiver(mWallpaperReceiver, filter); }else{ mWallpaperReceiver.setLauncher(this); } }现在,知道了壁纸的获取,那么,接下来我们自然而然想到的是:壁纸我已经获取到了,但是怎么样将它绘制在Workspace上面呢?注意,上面BroadcastReceiver获取到壁纸的时候调用了launcher.loadWallpaper()来完成壁纸加载的,在这个方法中,可以看到其调用了mWorkspace.loadWallpaper(mWallpaper);那么,就需要回到Workspace中了:
/** * 这里加载壁纸,需要重新绘制界面 * @param wallpaper */ public void loadWallpaper(Bitmap wallpaper) { wallpaperLoaded = true; mWallpaper = wallpaper; //要求重新绘制界面 requestLayout(); invalidate(); }这个方法仅仅要求重新绘制布局,那么,我们就知道,在绘制的方法中,应该会对壁纸进行相关的绘制。在dispatchDraw中,有对壁纸的处理,
/** * 壁纸本身可能并没有整个workspace那么宽 * 所以,屏幕滑动的时候,壁纸向右边滑动的距离需要根据mWallpaperOffset做相应的调整 */ float x = getScrollX()*mWallpaperOffset; //这里啥个意思,TODO: Log.v(TAG, "getRight-getLeft="+getRight()+"-"+getLeft()+"="+(getRight()-getLeft())); /** * getRight()-getLeft()=手机屏幕的宽度 */ if(x在这里,我们看到了,其通过canvas.drawBitmap(mWallpaper, x, y, mPaint);绘制了壁纸,这里关键的是x,y的计算,桌面可以横向滑动的,那么每次滑动后重新绘制的时候,这个x的值是在变化的,通过代码我们可以发现,其中有一个变量mWallpaperOffset,查找这个变量,在onMeasure中,对该变量进行了赋值: //加载壁纸 if(wallpaperLoaded){ wallpaperLoaded = false; mWallpaper = BitmapUtils.centerToFit(mWallpaper, width, height, getContext()); mWallpaperWidth = mWallpaper.getWidth(); mWallpaperHeight = mWallpaper.getHeight(); Log.v(TAG, "测量壁纸大小:"+mWallpaperWidth+","+mWallpaperHeight); } final int wallpaperWidth = mWallpaperWidth; //计算Wallpaper每次随着屏幕滑动移动的距离 if(wallpaperWidth > width){ /** * 计算壁纸滑动的速率 * 壁纸可以滑动的距离是count*width-wallpaperWidth * 屏幕可以滑动的距离是(count-1)*width * 这样,一除就是壁纸相对于屏幕滑动的速率了 */ //mWallpaperOffset = wallpaperWidth/(count*(float)width); mWallpaperOffset = (count*width-wallpaperWidth)/((count-1)*(float)width); }else { mWallpaperOffset = 1.0f; } Log.v(TAG, "wallpaper的offset:"+mWallpaperOffset);这样,当我们每次滑动的时候,Workspace在重绘的时候就会计算这个值,然后在dispatchDraw中首先绘制壁纸,然后绘制每个CellLayout。 好了,至此,我们应该清楚壁纸的添加机制了。 下一篇将揭晓item的拖拽之谜...
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2305
- 用户1336
- 访客11455538
每日一句
Talent without working hard is nothing.
没有努力,天份不代表什么。
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器
新会员