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


    }



   }
  }

  }

エラーがどこにあると思われるかを「MY PROBLEM IS HEREEE!!!」で指摘しました。コードで。事は canvas.translate(); にあります。

c.translate(mPosX, 0f); を使用する場合 onSurfacedChanged から取得した mPosX では、壁紙の画像の中央部分が希望どおりに表示されますが、背景全体をスクロールすることはできません。

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 に答える