一.可实现代码:
因为这几天逛csdn搜了好多"Wallpaper设置墙纸"的内容,
所以也找不到reference在哪里了,就不写了,有觉得侵权的就告诉我。
总之就记录下copy&paste之后能直接用的方法,为以后我再需要做个记录。
1. 创建一个自定义WallpaperService
public class LiveWallpaper extends WallpaperService {
private Bitmap bitmap;
// 实现动态壁纸必须要实现的抽象方法
@Override
public Engine onCreateEngine() {
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ac_eco_on);
return new MyEngine();
}
class MyEngine extends Engine {
private boolean mVisible; // 根据visibleChange的回调保存的visible状态
// 记录当前用户动作发生的位置
private float mTouchX = -1;
private float mTouchY = -1;
// 记录要绘制的矩形的数量
private int count = 1;
// 记录第一个矩形所需坐标变换的X、Y坐标的偏移
private int originX = 50, originY = 50;
// 定义画笔
private Paint mPaint = new Paint();
Handler mHandler = new Handler();
private final Runnable drawTarget = () -> drawFrame();
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
// 初始化画笔
mPaint.setARGB(76, 0, 0, 255);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
// 设置壁纸的触碰事件为true
setTouchEventsEnabled(true);
}
@Override
public void onVisibilityChanged(boolean visible) {
super.onVisibilityChanged(visible);
mVisible = visible;
if (visible) {
drawFrame();
} else {
// 如果界面不可见,删除回调
mHandler.removeCallbacks(drawTarget);
}
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) {
super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset);
drawFrame();
}
@Override
public void onDestroy() {
super.onDestroy();
// 删除回调
mHandler.removeCallbacks(drawTarget);
}
@Override
public void onTouchEvent(MotionEvent event) {
// 检测到滑动操作
if (event.getAction() == MotionEvent.ACTION_MOVE) {
mTouchX = event.getX();
mTouchY = event.getY();
} else {
mTouchX = -1;
mTouchY = -1;
}
super.onTouchEvent(event);
}
private void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas canvas = holder.lockCanvas();
if (canvas != null) {
canvas.drawColor(0xFFAADD);
// 在触碰点绘制图像
drawTouchPoint(canvas);
mPaint.setAlpha(76);
canvas.translate(originX, originY);
// 采用循环绘制count个图形
for (int i = 0; i < count; i++) {
canvas.translate(80, 0);
canvas.scale(0.95f, 0.95f);
canvas.rotate(20f);
canvas.drawRect(0, 0, 150, 75, mPaint);
}
holder.unlockCanvasAndPost(canvas);
// 调度下一次重绘
mHandler.removeCallbacks(drawTarget);
if (mVisible) {
count++;
if (count >= 50) {
Random rand = new Random();
count = 1;
originX += (rand.nextInt(60) - 30);
originY += (rand.nextInt(60) - 30);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 每隔0.1秒执行drawTarget一次
mHandler.postDelayed(drawTarget, 100);
}
}
}
private void drawTouchPoint(Canvas canvas) {
if (mTouchX >= 0 && mTouchY >= 0) {
// 设置画笔的透明度
mPaint.setAlpha(255);
canvas.drawBitmap(bitmap, mTouchX, mTouchY, mPaint);
}
}
}
}
这个动画绘制就是直接用了别的文章里的算法,后面再慢慢细化成我想要的样子的。总之,在这里谢谢那位dalao啦。
2. 在manifest中application标签下添加一个service配置
<service
android:name=".LiveWallpaper"
android:enabled="true"
android:permission="android.permission.BIND_WALLPAPER"
android:exported="true">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService"/>
</intent-filter>
<meta-data
android:name="android.service.wallpaper"
android:resource="@xml/wallpaper_file" />
</service>
这个service的android:name就是刚刚自定义的WallpaperService的类名(可能安卓用久了对Service了解多了自然而然就知道了吧,我认识安卓刚满一年,是第一次直接应用service,还有很多不足呢)
3.通过intent启动这个自定义的service
就直接在Activity里面启动了,后面放到点击事件里也可以直接用来着。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView(){
findViewById(R.id.setting_button).setOnClickListener(clickListener -> {
Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
new ComponentName(this, LiveWallpaper.class));
startActivity(intent);
});
}
}