2012-10-19 79 views
2

我在画布上绘制了两个位图(这是用于动态壁纸)的问题。事情是,在前面的小位图应该完全放置在背景位图的正确位置。当然,仿真器看起来不错(比方说480x800分辨率)。但是,当我在手机上检查它时(800x1280分辨率),它不适合正确的位置。Android - canvas drawBitmap和不同的分辨率?

我试着使用thise:

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

而不是硬像素,但它确实没有很好的为好。 下面是全班代码:

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

所以请,如果你能帮助任何人。

回答

0

使用ViewTreeObserver来测量视图/屏幕尺寸并将位图与结果坐标放在一起。

这里的一个示例代码测量值的布局的宽度和高度

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


} 
     }); 
+0

谢谢,但我不明白。事情是,我不使用动态壁纸的布局,所以如果我理解得很好,就没有看法。我只是画画布和位图。那么我可以在我的例子中使用这个ViewTreeObserver吗? – Lucass

+0

对不起,我以为你正在画一个视图中的画布。也许你可以利用SurfaceHolder回调,但我不确定。我稍后会检查它,现在我无法使用。 –

0
  1. 获取密度

    DisplayMetrics metrics; 
    metrics = new DisplayMetrics(); 
    metrics = new DisplayMetrics(); 
    getWindowManager().getDefaultDisplay().getMetrics(metrics); 
    float density = metrics.density; 
    
  2. 应用这样

    Canvas canvas = new Canvas(bitmap); 
    canvas.drawBitmap(ksiezyc, density * wx,density * wy, paintMoon);