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);


    }



   }
  }

  }

我指出我认为错误出在“我的问题在这里!!!” 在代码中。东西在 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 时不起作用。

所以任何人都可以帮助我在切换主屏幕时让我的动态壁纸图像居中显示并滚动。先感谢您。

4

1 回答 1

0

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

前任:

mPixels = (0- screenWidth)*xOffset;

mPixels 应该从 xPixelOffset (我的代码上的 xPixel )获取值,而 screenWidth 是通过以下方式从 OnSurfaceChanged 获取的:

super.onSurfaceChanged(holder, format, width, height);
screenWidth= width;
于 2012-07-11T11:15:06.550 回答