본문 바로가기

Android/Center of Screen

Android Center of Screen

안드로이드에서 화면의 중심좌표를 구하는 방법

상태바와 타이틀바를 포함한 전체 화면의 높이와 크기 int width = getWindowManager().getDefaultDisplay().getWidth(); int height = getWindowManager().getDefaultDisplay().getHeight(); 만약 상태바와 타이틀바가 있는 화면의 수직 중앙에 무언가를 출력하고자 할 때.... int cx = width/2; int cy = height/2; canvas.drawBitmap(bitmap, cx, cy, null); 위와 같은 방법으로 화면의 중앙에 이미지를 출력하고자 한다면 실제로는 화면 중앙보다 더 낮은 곳에 이미지가 출력된다. 즉, 중앙보다 [상태바 높이+타이틀바 높이] 만큼 아래에 이미지가 그려진다. 상태바와 타이틀바가 있을 때의 원점은 타이틀바의 아래 왼쪽 끝으로 설정되어 있기 때문이다. 그러므로 컨텐츠 영역의 중앙에 이미지를 출력하면 다음과 같이 좌표를 보정한 후에 적용해야 한다. int cy = height/2-(상태바 높이+타이틀바 높이);


MainActivity.java

package com.example.androidapp; import android.app.Activity; import android.graphics.Rect; import android.os.Bundle; import android.os.Handler; import android.util.DisplayMetrics; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* 상태바와 타이틀바의 높이를 제외한 화면의 높이를 구하는 방법 DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int myHeight = 0; /* 상태바의 높이는 해상도에 따라서 각각 50, 38, 25, 19 픽셀로 정해져 있고 상태바와 타이틀바의 높이는 동일함 */ switch (metrics.densityDpi) { case DisplayMetrics.DENSITY_XHIGH: myHeight = getWindowManager().getDefaultDisplay().getHeight() - 50*2; Log.i("display", "xhigh,"+myHeight); break; case DisplayMetrics.DENSITY_HIGH: myHeight = getWindowManager().getDefaultDisplay().getHeight() - 38*2; Log.i("display", "high,"+myHeight); break; case DisplayMetrics.DENSITY_MEDIUM: myHeight = getWindowManager().getDefaultDisplay().getHeight() - 25*2; Log.i("display", "medium/default,"+myHeight); break; case DisplayMetrics.DENSITY_LOW: myHeight = getWindowManager().getDefaultDisplay().getHeight() - 19*2; Log.i("display", "low,"+myHeight); break; default: Log.i("display", "Unknown density"); } /* 화면에 뷰가 일단 한번이라도 보여진 후에 화면의 상태바와 타이틀바의 높이를 구하는 방법 */ Button button = new Button(this); button.setText("START"); setContentView(button); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // 아래의 코드는 화면에 뷰가 한번은 출력된 후에 실행되어야 상태바와 타이틀바의 값이 구해진다. Rect rect= new Rect(); Window window = getWindow(); window.getDecorView().getWindowVisibleDisplayFrame(rect); int statusBarHeight= rect.top; int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop(); int titleBarHeight= contentViewTop - statusBarHeight; Log.i("상태바의 높이", "TitleBarHeight"+titleBarHeight+"StatusBarHeight"+statusBarHeight);

int cx = getWindowManager().getDefaultDisplay().getWidth()/2; int cy = (getWindowManager().getDefaultDisplay().getHeight()-statusBarHeight-titleBarHeight)/2; setContentView(new Tank(MainActivity.this,cx, cy)); } }); } }


Tank.java

package com.example.androidapp; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.util.AttributeSet; import android.view.View; import android.view.WindowManager; public class Tank extends View { Canvas cacheCanvas; Bitmap backBuffer; int cx, cy; // 화면의 중심좌표 public Tank(Context context, int cx, int cy) { super(context); this.cx = cx; this.cy = cy; init(); } public Tank(Context context, AttributeSet attrs) { super(context, attrs); init(); } int width, height, sx, sy; Bitmap bitmapTank, invTank, tank; Matrix matrix, horInvMatrix; int delta = -5; private void init() { System.out.println("init실행됨"); WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); width = wm.getDefaultDisplay().getWidth(); height = wm.getDefaultDisplay().getHeight(); cacheCanvas = new Canvas(); bitmapTank = BitmapFactory.decodeResource(getResources(), R.drawable.tank); backBuffer = Bitmap.createBitmap( bitmapTank.getWidth(), bitmapTank.getHeight(), Bitmap.Config.ARGB_8888); cacheCanvas.setBitmap(backBuffer); sx = width/2-(bitmapTank.getWidth()/2); sy = cy-(bitmapTank.getHeight()/2); matrix = new Matrix(); horInvMatrix = new Matrix(); horInvMatrix.setScale(-1, 1); invTank = Bitmap.createBitmap(bitmapTank, 0, 0, bitmapTank.getWidth(), bitmapTank.getHeight(), horInvMatrix, false); tank = bitmapTank; new Thread(){ public void run() { while(true) { if(sx<=0) { tank = invTank; delta *= -1; }else if(sx >= width-backBuffer.getWidth()){ tank = bitmapTank; delta *= -1; } cacheCanvas.drawBitmap(tank, matrix, null); sx+=delta; postInvalidate(); try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } }; }.start(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(backBuffer, sx, sy, null); } }