0

我正在开发我的第一个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); 


    } 



    } 
    } 

    } 

我指出,我认为错误是一个“我的问题是HEREEEE !!!”在代码中。事情在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时无法工作。

所以,任何人都可以帮助我的动态壁纸图像显示居中和滚动时请切换主屏幕。先谢谢你。

+0

PS:我已经检查logcat和为什么它在第二次启动时工作,当我使用c.translate((float)mPixels,0f);.出于某种原因,当我第一次安装并启动动态壁纸时,来自public void onOffsetsChanged(我在此命名为int xPixels)的xPixelOffset返回值为0,这使得动态壁纸只显示左边的部分背景(像我使用c.translate(0,0f);)。如果我再次运行它,那么XPixelOffset会得到一个值并使其工作。 – FrankieWar 2012-07-10 01:31:53

+0

任何人都可以帮助我解释为什么发生这种情况以及如何解决它。如果我无法避免它,另一种方法来获得值xPixelOffset(xPixel在我的情况) – FrankieWar 2012-07-10 01:32:34

回答

0

嗯,我仍然不知道为什么有时来自onOffsetChanged的xPixelOffset值(我的代码上的xPixel)返回0,但我设法为可能出现此异常的设备获得替代解决方案。 如果这发生在别人身上,我意识到xPixelOffset也可以通过获取设备屏幕宽度并乘以onOffsetChanged中的xOffset来获得。可以获取宽度并将其存储在OnSurfaceChanged的新变量中,在该变量中可以获取设备屏幕的宽度和高度。

EX:

mPixels = (0- screenWidth)*xOffset; 

凡兆像素应当从xPixelOffset(在我的代码xPixel)所获得的价值,并且屏幕宽度从通OnSurfaceChanged获得:

super.onSurfaceChanged(holder, format, width, height); 
screenWidth= width;