我正在开发我的第一个 android 项目,这是一个动态壁纸,我设法通过教程、示例,甚至在这里找到的代码来完成工作,但我仍然有一个问题无法完成。我希望我的动态壁纸在用户切换主屏幕时使用图像进行视差滚动。
这是我的代码::
package com.livewallpaper.mw3lwp;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.WindowManager;
public class ModernWarfare3LiveWallpaper extends WallpaperService {
private final Handler mHandler = new Handler();
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public Engine onCreateEngine() {
return new CubeEngine();
}
class CubeEngine extends Engine {
private final Paint mPaint = new Paint();
private float mPosY;
private float mPosX;
//private float mPosYBackup;
private boolean mAnime = true;
private Matrix mMatrix = new Matrix();
public int bgcycle = 0;
public Bitmap myBg;
public int idx = 0;
private float mPixels;
private final Runnable mDrawAnim = new Runnable() {
public void run() {
drawFrame();
}
};
private boolean mVisible;
private static final int NUM_RES = 50;
//private final Bitmap[] mPics = new Bitmap[NUM_RES];
public int getScreenOrientation() {
Display screen= ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int orientation = getResources().getConfiguration().orientation;
// UNDEFINED
if(orientation==Configuration.ORIENTATION_UNDEFINED){
//Configuration config = getResources().getConfiguration();
if(orientation==Configuration.ORIENTATION_UNDEFINED){
//if height and widht of screen are equal then
// it is square orientation
if(screen.getWidth()==screen.getHeight()){
orientation = Configuration.ORIENTATION_SQUARE;
}else{ //if widht is less than height than it is portrait
if(screen.getWidth() < screen.getHeight()){
orientation = Configuration.ORIENTATION_PORTRAIT;
}else{ // if it is not any of the above it will defineitly be landscape
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
}
}
}
//
// Query what the orientation currently really is.
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
// The following message is only displayed once.
return orientation/*= 1*/; // Portrait Mode
}else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// The following message is only displayed once.
return orientation/*= 2*/; // Landscape mode
}
return orientation;
}
public void updateBG() {
idx += 1;
if (idx == NUM_RES) {idx = 0;}
Resources res = getResources();
int id = res.getIdentifier("n" + (idx + 1), "drawable", "com.livewallpaper.mw3lwp");
myBg = BitmapFactory.decodeResource(res, id);
}
CubeEngine() {
Resources res = getResources();
//for (int i = 0; i< NUM_RES; i++) {
int id = res.getIdentifier("n" + (idx + 1), "drawable", "com.livewallpaper.mw3lwp");
myBg = BitmapFactory.decodeResource(res, id);
// if (i==NUM_RES) i=0;
// }
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
setTouchEventsEnabled(false);
}
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mDrawAnim);
}
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(mDrawAnim);
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//if landscape
if (getScreenOrientation() == 2){
super.onSurfaceChanged(holder, format, width, height);
float w = myBg.getWidth();
float h = myBg.getHeight();
float s = width / (float)w;
mMatrix.reset();
mMatrix.setScale(s, s);
mPosY = (height - (h * s)) / 2f;
//mPixels= 0;
//mPosYBackup= mPosY;
drawFrame();
}
//
//if portrait
else {
super.onSurfaceChanged(holder, format, width, height);
float w = myBg.getWidth();
float h = myBg.getHeight();
float s = height / (float)h;
mMatrix.reset();
mMatrix.setScale(s, s);
//mMatrix.postScale(s, s, 0, 0);
// mPosY = 0f;
mPosX= (width - (w * s)) / 2f;
drawFrame();
}
//
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(mDrawAnim);
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xStep, float yStep, int xPixels, int yPixels) {
// Agregado recien
//if landscape
if (getScreenOrientation() == 2){
super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels);
//mPosY= mPosYBackup;
drawFrame();
}
//if portrait
else{
super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels);
mPixels = xPixels;
//mPosY=0f;
drawFrame();
}
// Fin Agregado
}
@Override
public void onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
mAnime = !mAnime;
}
super.onTouchEvent(event);
}
void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
// draw something
drawAnim(c);
//drawTouchPoint(c);
}
} finally {
if (c != null) holder.unlockCanvasAndPost(c);
}
// Reschedule the next redraw
mHandler.removeCallbacks(mDrawAnim);
if (mVisible && mAnime) {
mHandler.postDelayed(mDrawAnim, 0);
}
}
void drawAnim(Canvas c) {
// if portrait
if(getScreenOrientation() == 1){
c.save();
//if (this.isPreview()) {
//c.translate(/*(float)*/mPosX, 0f);
//}
// MY PROBLEM HEREEEEE!!!! IM NOT USING BOTH
c.translate(/*(float)*/mPosX, 0f);
c.translate((float)mPixels, 0f);
updateBG();
c.drawBitmap(myBg, mMatrix, mPaint);
//c.drawBitmap(myBg, 0, 0, mPaint);
if (mAnime) ++idx;
if (idx == NUM_RES) idx = 0;
c.restore();
}
//end if portrait
// if landscape
if(getScreenOrientation() == 2){
c.save();
c.translate(0, mPosY);
updateBG();
c.drawBitmap(myBg, mMatrix, mPaint);
if (mAnime) ++idx;
if (idx == NUM_RES) idx = 0;
c.restore();
}
// end if landscape
//c.drawBitmap(mPics[idx], mMatrix, mPaint);
}
}
}
}
我指出我认为错误出在“我的问题在这里!!!” 在代码中。东西在 canvas.translate();
如果我使用 c.translate(mPosX, 0f); mPosX 从 onSurfacedChanged 获得,壁纸中图像的中心部分以我想要的方式显示,但它不会滚动整个背景。
如果我使用 c.translate((float)mPixels, 0f); 其中 mPixels 是从 onOffSetChanged 获得的,它只显示壁纸的左侧部分/区域。
最后,如果我将 mPosX 名称更改为 mPixels,c.translate((float)mPixels, 0f); 从 onSurfacedChanged 和 onOffSetChanged 中获取值。它不适用于第一次执行。您可以看到壁纸首先居中,然后返回仅显示壁纸的左侧部分。如果我在 eclipse 上第二次运行它并在我的手机上再次设置它,那么它将按我的意愿工作,中间主屏幕上图像的中心部分,并在切换主屏幕时滚动背景。但问题是它在第一次执行时不起作用,导致导出为 apk 时不起作用。
所以任何人都可以帮助我在切换主屏幕时让我的动态壁纸图像居中显示并滚动。先感谢您。