有趣的手机壁纸——水印壁纸

news/2024/11/16 12:35:08/

此应用的代码地址在我的github

此应用已上线,下载地址http://shouji.baidu.com/software/23371524.html


最近看了一个水波纹效果的案例视频,大家可以看看。这个案例实现的效果就是点击或滑动屏幕,在点击和滑动过的地方就会画圆,同时画的圆会慢慢变小,慢慢变淡,直至消失。看着挺好看也挺好玩,然而前一阵子又发布了一个透明壁纸的博客。所以就想能不能把这个水波纹弄到壁纸上,于是这个水印壁纸就诞生了。

因为是新手,所以遇到了很多问题,有些甚至是很基础的问题,但是好在百度了一大堆,基本问题都解决了,总的来说自己的基础还是太差了。

好了看代码,首先要先做壁纸,壁纸的制作可以看我的上一个博客手机透明壁纸,这里就不细说了。

接下来就是在壁纸服务里加入画图的操作。

 Handler mHandler = new Handler();// 重复执行的一个方法private final Runnable drawTarget = new Runnable() {public void run() {drawFrame();}};

这里面定义了一个handler,利用它来重复的调用画图方法,来不断地绘制水印。需要注意的是,在这里绘图我们是直接在surfaceview上进行绘图的,这是另外一个线程,不同于只能在主线程更新UI的那个线程。并且它在底层实现机制中实现了双缓冲机制,所以一般不会阻塞线程。更多的关于surfaceview的知识可以去百度,因为我也是百度的。

接下来就是画图方法了。

private void drawFrame() {// 获取该壁纸的SurfaceHolderfinal SurfaceHolder holder = getSurfaceHolder();Canvas c = null;try {// 获取Canvasc = holder.lockCanvas();if (c != null) {isRuning = true;c.save();Paint paint1 = new Paint();paint1.setAlpha(255);paint1.setAntiAlias(true);paint1.setStyle(Paint.Style.FILL);c.drawBitmap(res,0,0,paint1);// 在触碰点绘制图像drawTouchPoint(c);for (int i = 0; i < wList.size(); i++) {Wave w = wList.get(i);int alpha = w.p.getAlpha();if (alpha == 0) {wList.remove(i);//删除i以后,总数会减少一,否则会漏掉一个对象i--;continue;}alpha -= 10;if (alpha < 10) {alpha = 0;}w.p.setAlpha(alpha);}if (wList.size() == 0) {isRuning = false;}}} finally {if (c != null)holder.unlockCanvasAndPost(c);}mHandler.removeCallbacks(drawTarget);// 调用重绘if (mVisible && isRuning) {//重复画图mHandler.postDelayed(drawTarget,50);}}

private void drawTouchPoint(Canvas c) {for (int i = 0; i < wList.size(); i++) {Wave wave = wList.get(i);if (waterId == 0) {bitmap1 = BitmapFactory.decodeResource(getResources(), R.mipmap.heart_icon);}else{bitmap1 = BitmapFactory.decodeResource(getResources(),waterId);}c.drawBitmap(bitmap1,wave.cx,wave.cy,wave.p);}}

绘图的坐标点可以通过onTouchEvent方法获得,点击屏幕画出水印的效果基本完成了,接下来就是遇到的问题了。

首先这样壁纸背景只能是个单色,但是壁纸怎么能这样呢。所以我就又百度了好长时间,最后找出一个方法就是在这个基础上再在画布上画一个图,利用这张图当背景。代码如下

@Overridepublic void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {super.onSurfaceChanged(holder, format, width, height);if (path == null){bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_back);}else {bitmap = BitmapFactory.decodeFile(path);}WindowManager wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);int width2 = wm.getDefaultDisplay().getWidth();int height2 = wm.getDefaultDisplay().getHeight();int width1 = bitmap.getWidth();int height1 = bitmap.getHeight();Matrix matrix = new Matrix();if (width1 >= width2 && height1 >= height2){float scaleWight1 = ((float)width2)/width1;float scaleHeight1 = ((float)height2)/height1;float Scale;if (scaleWight1 - scaleHeight1 >= 0){Scale = scaleWight1;}else {Scale = scaleHeight1;}matrix.preScale(Scale,Scale);res = Bitmap.createBitmap(bitmap,0,0,width1,height1,matrix,true);}if (width1 < width2 && height1 < height2){float scaleWight = ((float)width2)/width1;float scaleHeight = ((float)height2)/height1;float Scale2;if (scaleWight - scaleHeight >= 0){Scale2 = scaleWight;matrix.preScale(Scale2,Scale2);int y2 = (int)(height1 - height1/Scale2);Bitmap FirstBi = Bitmap.createBitmap(bitmap,0,0,width1,height1,matrix,true);int FirstWid = FirstBi.getWidth();int FirstHei = FirstBi.getHeight();res = Bitmap.createBitmap(FirstBi,0,y2/2,FirstWid,FirstHei-y2/2);}else {Scale2 = scaleHeight;matrix.preScale(Scale2,Scale2);int x2 = (int)(width1 - width1/Scale2);Bitmap FirstBit = Bitmap.createBitmap(bitmap,0,0,width1,height1,matrix,true);int FirstWidth = FirstBit.getWidth();int FirstHeight = FirstBit.getHeight();res = Bitmap.createBitmap(FirstBit,x2/2,0,FirstWidth-x2/2,FirstHeight);}}if (width1 >= width2 && height1 < height2){float scale3 = ((float)height2)/height1;matrix.preScale(scale3,scale3);int x3 = (int)(width1 - width1/scale3);Bitmap Bitmap3 = Bitmap.createBitmap(bitmap,0,0,width1,height1,matrix,true);int FirstWidth3 = Bitmap3.getWidth();int FirstHeight3 = Bitmap3.getHeight();res = Bitmap.createBitmap(Bitmap3,x3/2,0,FirstWidth3-x3/2,FirstHeight3);}if (width1 < width2 && height1 >= height2){float scale4 = ((float)width2)/width1;matrix.preScale(scale4,scale4);int y3 = (int)(height1 - height1/scale4);Bitmap Bit4 = Bitmap.createBitmap(bitmap,0,0,width1,height1,matrix,true);int FirstWidth4 = Bit4.getWidth();int FirstHeight4 = Bit4.getHeight();res = Bitmap.createBitmap(Bit4,0,y3/2,FirstWidth4,FirstHeight4-y3/2);}Canvas ca = holder.lockCanvas();Paint paint1 = new Paint();paint1.setAlpha(255);paint1.setAntiAlias(true);paint1.setStyle(Paint.Style.FILL);ca.drawBitmap(res,0,0,paint1);holder.unlockCanvasAndPost(ca);}

其实画图的方法还和上面一样,但是又多出了好多判断代码,这就是我遇到的另一个问题。那就是我们可以随便拿一张图片来当壁纸,但是我们的图片尺寸基本和自己的手机屏幕尺寸是不配合的。所以我们就得裁剪图片,使图片适应屏幕。其中matrix.prescale方法只是缩放了图片,但是对于有些图片并不能得到主要的部分,所以我们还要对图片进行偏移。我采用的是先缩放,再偏移的方法也就是上面看到的两次使用createBitmap方法了。代码写的很乱,也懒得改了,因为想这个办法想了好长时间。


最后就是我们要能自己选择手机里的图片作为壁纸,这样可用性会更高。这也就遇到了一个新的问题,那就是如何把我们选择的图片传到我们的壁纸服务中。一开始我就想的是用intent传递数据,这是标准的用法。但是利用启动服务的方法根本传不进去,因为这个壁纸服务根本不是我去启动的,而是手机内部的壁纸管理器去启动的,具体内部的实现我也不知道是怎么回事,所以这个方法就行不通了。后来在看了鸿洋的一个博客,是视频做壁纸的,他上面是用的广播来控制声音开启的。所以我就也仿着去弄,结果是能传递数据进去了,但是只有当壁纸启动起来,才能进行壁纸的更换。具体的情况大家可以试试,这是因为注册的是动态广播只有当服务启动了,才能接收广播。再后来我改了改就直接利用了静态方法来传递数据,以前还真不知道这个方法。不过百度了一下,这个方法好像容易造成传递的数据为空,所以这并不能算最好的方法,还是得慎用。但是我目前还没遇到过为空的时候。

public static void ImagePath(Context context, String data){path = data;}


最后完整代码我的github

应用已上线,下载地址http://shouji.baidu.com/software/23371524.html








http://www.ppmy.cn/news/249159.html

相关文章

android视频动态壁纸app,手机壁纸视频动态壁纸

手机壁纸视频动态壁纸直接的将视频内容设置为你的动态壁纸&#xff0c;让用户能够将手机上面的视频内容设置为你桌面上的动态壁纸&#xff0c;你可以将一些极为精彩或者是好看的视频内容截取下来&#xff0c;然后通过这款软件来完成设置&#xff0c;软件看起来非常的简单但是也…

android 手机壁纸源码,Android设置手机壁纸-源码(WallPaper)

Android设置手机壁纸-源码(WallPaper) /** * Andorid设置手机屏幕的壁纸 * * @description: * @author ldm * @date 2016-5-4 下午3:08:56 */ public class SetWallpaperActivity extends Activity {// WallpaperManager类:系统壁纸管理。通过它可以获得当前壁纸以及设置指定…

python制作手机壁纸_用Python生成自己独一无二的手机壁纸

已经12月份了&#xff0c;马上就要过年了&#xff0c;要不要换一个喜气洋洋、洋洋洒洒、洒扫应对、对牛弹琴的手机壁纸呢&#xff1f; 今天小编给大家表演的节目是&#xff1a;用Python生成自己独一无二的手机壁纸。 首先我们需要选择一个现成的手机壁纸作为模板&#xff0c;我…

android壁纸和手机屏幕之间要怎么对应,android手机壁纸

安卓手机怎样获取当前壁纸&#xff1f; 手机设置锁屏壁纸方法&#xff1a; 方式1&#xff1a;待机界面-长按屏幕弹出主屏界面-壁纸-左上角选择“锁定屏幕”-从相册或内置墙纸选择图片即可。 方式2&#xff1a;设定-(显示/显示和墙纸)-壁纸(墙纸)-选择“锁定屏幕”-选择图片来源…

android手机壁纸尺寸,安卓手机壁纸尺寸选择攻略:屏幕分辨率≠壁纸分辨率

安卓手机壁纸尺寸怎么选择&#xff1f;安卓手机跟屏幕分辨率一样大小的壁纸为什么不能用?Android手机壁纸的最佳分辨率是多少?下面绿茶小编将带你一起来了解安卓手机用壁纸&#xff0c;让你选择最适合自己的手机壁纸。 1、安卓手机壁纸的分辨率 ≠ 安卓手机屏幕分辨率 像iPho…

Python爬取手机壁纸

小编就爬取知乎上面那些好看的手机壁纸吧&#xff0c;各式各样都有&#xff01; 代码很简单 只有14行&#xff0c;只有14行&#xff0c;只有14行&#xff01;重要的事情说三遍&#xff01;&#xff01;&#xff01; from urllib import request #从urllib库里导入request模块…

手机壁纸尺寸android,手机壁纸分辨率怎么选 安卓手机壁大小选择技巧

现在使用安卓手机的人好多了,一个好的手机壁纸自然是大家的追求,那么要怎么挑选适合自己安卓手机的手机壁纸呢,我们知道手机壁纸的大小最好与手机屏幕分辨率才能达到最佳的匹配效果,如果壁纸过小,则会拉伸图片,使得手机壁纸清晰度降低,如果壁纸过大,则手机壁纸处于缩放…

手机壁纸API

不分类别获取壁纸接口 url:http://service.picasso.adesk.com/v1/vertical/vertical 拼接参数: limit:返回数量adult:布尔值,暂时未知first:数字,如1skip:略过数量order:值 hot为favs, newurl 示例:http://service.picasso.adesk.com/v1/vertical/vertical?limit…