2

I have this issue with drawing for example two bitmaps on canvas(it's for the live wallpaper). Thing is that small bitmap that is at front should be placed exactly in right place of the background bitmap. It looks good on emulator of course (let's say 480x800 resolution). But when I check it on my phone (800x1280 res) it doesn't fit the right place.

I've tried to use thise:

    int pixel = 120;
final float scale = getResources().getDisplayMetrics().density;
int dip = (int) (pixel* scale + 0.5f);

instead of hard pixels, but it did no good as well. Below is the whole class code:

public class DemoWallpaperService extends WallpaperService {

@Override
public Engine onCreateEngine() {
    return new DemoWallpaperEngine();
}

private class DemoWallpaperEngine extends Engine {
    private boolean mVisible = false;
    private final Handler mHandler = new Handler();

     int x=0,y=0,a=255,i=-1, a1=255, i1=-1;
     float r=0,rs=1;
     float rx1=10, rxs=-1;

     private Matrix mMatrix = new Matrix();
     private Matrix mMatrix1 = new Matrix();
     private Matrix mMatrixRotate1 = new Matrix();
     private Matrix mMatrixRotate2 = new Matrix();

     public Bitmap spaceShip = BitmapFactory.decodeResource(getResources(), R.drawable.spaceship);
     public Bitmap background= BitmapFactory.decodeResource(getResources(), R.drawable.back2short2j);
     public Bitmap wyspa= BitmapFactory.decodeResource(getResources(), R.drawable.wyspa22g);
     public Bitmap ksiezyc = BitmapFactory.decodeResource(getResources(), R.drawable.ksiezyc);
     public Bitmap reflektorfront= BitmapFactory.decodeResource(getResources(), R.drawable.reflektorwyspa);

     private float mPixels;
     private float mPixels1;



    private final Runnable mUpdateDisplay = new Runnable() {
    @Override
    public void run() {
        draw();
    }};



    private void draw() {
       SurfaceHolder holder = getSurfaceHolder();
       Canvas c = null;

       Display d = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
       int wx= d.getWidth();
       int wy= d.getHeight();

       try {
           Runtime.getRuntime().gc();
          c = holder.lockCanvas();
          c.save();

          if (c != null) {

              Paint paintMoon = new Paint();

              if(a1<=15){
                  i1=1;
              }
              else if(a1>=255){
                  i1=-1;
              }
              a1+=5*i1;
              paintMoon.setAlpha(a1);

              c.translate((float)mPixels, 0f);
              c.drawBitmap(background, mMatrix, null);
              c.drawBitmap(ksiezyc, 1027*wx/480,15*wy/800, paintMoon);

              if(rx1<=-15){
                  rxs=1;
              }
              else if(rx1>=15){
                  rxs=-1;
              }
              rx1+=rxs*0.7;

              c.translate((float)mPixels1, 0f);
              //reflektor wyspa back
              mMatrixRotate2.setTranslate(340*wx/480,300*wy/800);
              mMatrixRotate2.preRotate(rx1,reflektorfront.getWidth()/2,20);
              c.drawBitmap(reflektorfront, mMatrixRotate2, null);


              c.drawBitmap(wyspa, mMatrix1, null);

              if(r<=-15){
                  rs=1;
              }
              else if(r>=15){
                  rs=-1;
              }
              r+=rs*0.5;


              mMatrixRotate1.setTranslate(160*wx/480,380*wy/800);

              mMatrixRotate1.preRotate(r,reflektorfront.getWidth()/2,20);

              c.drawBitmap(reflektorfront, mMatrixRotate1, null);


              if(x<c.getWidth()){
              x+=3;}
              else{x=0;}
              if(y<c.getHeight()){
              y+=3;}
              else{y=0;}
              Paint paint = new Paint();


              if(a<=5){
                  i=1;
              }
              else if(a>=255){
                  i=-1;
              }
              a+=10*i;
              paint.setAlpha(a);

              c.drawBitmap(spaceShip,x,y,paint);


                 c.restore();

          }
       } finally {
          if (c != null)
             holder.unlockCanvasAndPost(c);
       }
       mHandler.removeCallbacks(mUpdateDisplay);
       if (mVisible) {
           mHandler.postDelayed(mUpdateDisplay, 10);
       }
    }
    @Override
    public void onOffsetsChanged(float xOffset, float yOffset,
             float xStep, float yStep, int xPixels, int yPixels){

        super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels);                   
         mPixels = xPixels*7/4;

         mPixels1 = 500+xPixels;

            draw();
    }



    @Override
    public void onVisibilityChanged(boolean visible) {
        mVisible = visible;
        if (visible) {
            draw();
        } else {
            mHandler.removeCallbacks(mUpdateDisplay);
        }
    }

     @Override
      public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {

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

         float w = background.getWidth();
         float h = background.getHeight();
         float s = height / (float)h;
         float z = height / (float)h;
         mMatrix.reset();
         mMatrix1.reset();
         mMatrixRotate1.reset();
         mMatrixRotate2.reset();

         mMatrix.setScale(s, s);
         mMatrix1.setScale(z, z);
         mMatrixRotate1.setScale(s, s);

         draw();
      }

    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder) {
        super.onSurfaceDestroyed(holder);
        mVisible = false;
        mHandler.removeCallbacks(mUpdateDisplay);
    }


    @Override
     public void onCreate(SurfaceHolder surfaceHolder) {
         super.onCreate(surfaceHolder);

         setTouchEventsEnabled(false);
     }

    @Override
    public void onDestroy() {
         super.onDestroy();
         mVisible = false;
         mHandler.removeCallbacks(mUpdateDisplay);
    }
}    

so please help anyone if You can.

Lucass
  • 147
  • 3
  • 12

2 Answers2

0

Use ViewTreeObserver to measure the view/screen dimensions and place your bitmap with the resulting coordinates.

Here's a sample code the measure a layout's width and height

final RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_layout);
        ViewTreeObserver vto = mainLayout.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                final int viewWidth = mainLayout.getMeasuredWidth();
                final int viewHeight = mainLayout.getMeasuredHeight();
                if (Constants.LOG_ENABLED) {
                    Log.i(TAG, "Width: " + viewWidth);
                    Log.i(TAG, "Height: " + viewHeight);
                }
                /**
                 * Delete tree observer
                 */
                ViewTreeObserver obs = mainLayout.getViewTreeObserver();
                obs.removeGlobalOnLayoutListener(this);


}
        });
C.d.
  • 9,932
  • 6
  • 41
  • 51
  • Thanks, but I don't get it. The thing is I don't use layouts for Live Wallpaper, so there's no view as well if I understand it well. There's just canvas and bitmaps i draw on it. So can I use this ViewTreeObserver in my case and how? – Lucass Oct 19 '12 at 20:21
  • Sorry I thought you are drawing you canvas inside a view. Maybe you can exploit the SurfaceHolder callbacks but I am not sure. I will check it later I am not available right now. – C.d. Oct 19 '12 at 20:37
0
  1. Get density

    DisplayMetrics metrics;
    metrics = new DisplayMetrics();
    metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    float density = metrics.density;
    
  2. Apply like this

    Canvas canvas = new Canvas(bitmap);
    canvas.drawBitmap(ksiezyc, density * wx,density * wy, paintMoon);
    
Khalid Habib
  • 1,100
  • 1
  • 16
  • 25