2012-07-09 105 views
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;