[안드로이드]화면 해상도 구하기 및 View의 가로,세로 구하기

Posted by ITPangPang
2016. 4. 23. 15:51 안드로이드(android)/View



[안드로이드]화면 해상도 구하기 및 

특정 View의 가로,세로 구하기



- 이번글에서는 첫번째로 디바이스의 해상도를 구해보겠습니다.


- 두번째로는 사실 이것때문에 이 글을 쓰는건데 특정 View, Layout의 크기를 구해야할 경우가 있습니다.





첫번째로,

단말기의 해상도

구해보겠습니다

[MainActivity.java]

public class MainActivity extends ActionBarActivity
{
TextView tv;
int width;
int height;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.tv);

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;


tv.setText("x=>"+width+",y=>"+height);
}
}



아주 잘나옵니다

720x1280



두번째로,

특정 View의 

가로,세로(너비,높이)

Width, Height를 

구해보겠습니다.


getWidth, getHeight라는

놈이 있습니다.


그냥 사용하면 됩니다.

TextView로

테스트를 해보겠습니다.


[activity_main.xml]

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">

<TextView
android:id="@+id/tv"
android:text="@string/hello_world"
android:layout_width="match_parent"
android:layout_height=
"wrap_content" />

</LinearLayout>



[activity_main.xml]

public class MainActivity extends ActionBarActivity
{
TextView tv;
int width;
int height;
@Override
protected void onCreate(Bundle savedInstanceState)
{
Log.d("ITPANGPANG", "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.tv);
width = tv.getWidth();
height = tv.getHeight();

Log.d("ITPANGPANG", "x=>" + width + ",y=>" + height);
}
}





코드를 짜고

돌려봤는데?

???

이상합니다

x,y가 0이랍니다....


여기서 중요한 부분이

나옵니다.


화면이 뿌려지기전에

숨겨져있는 메서드가

있습니다..


onWindowFocusChange라는놈입니다

이 메서드는 화면 포커스가

변할때 호출되는 메서드입니다.


뭐 설명보다는 바로 사용해보겠습니다.

요즘 이것을 많이 강조하는데

(제가 하두 자주 쓰다보니..)

Alt+Insert누른후 Override Methods..

선택합니다



onWindosF까지 치면 위 사진처럼 나옵니다

거기서 OK를 누른후에 가져옵니다


public class MainActivity extends ActionBarActivity
{
TextView tv;
int width;
int height;
@Override
protected void onCreate(Bundle savedInstanceState)
{
Log.d("ITPANGPANG", "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.tv);
width = tv.getWidth();
height = tv.getHeight();
Log.d("ITPANGPANG", "x=>" + width + ",y=>" + height);
}

@Override
public void onWindowFocusChanged(boolean hasFocus)
{
Log.d("ITPANGPANG","onWindowFocusChanged");
super.onWindowFocusChanged(hasFocus);
}
}


자 이렇게 가져와서 한번 써보고

프로그램을 돌려봅니다.




결과를 보니 onCreate 이후에

onWindowFoucesChanged가 

호출되는 것을 확인 할 수 있습니다.


이 말이 무엇이나 하면

화면포커스가 바뀔때

onWindowFocusChanged가 

호출되는데


포커스가 바뀌기전에

onCreate가 먼저

호출되버려서

TextView를 읽어버리기전에

먼저 x,y값을 구하려고 하니

0이 떨어지는 겁니다.


자 그렇다면 

제대로 값을 구하기 

위해서는??


순서를 조금 바꿔주면 

됩니다.


public class MainActivity extends ActionBarActivity
{
TextView tv;
int width;
int height;
@Override
protected void onCreate(Bundle savedInstanceState)
{
Log.d("ITPANGPANG", "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
public void onWindowFocusChanged(boolean hasFocus)
{
Log.d("ITPANGPANG","onWindowFocusChanged");
tv = (TextView)findViewById(R.id.tv);
width = tv.getWidth();
height = tv.getHeight();
Log.d("ITPANGPANG", "x=>" + width + ",y=>" + height);
}
}



자 순서를 조금 바꿔주니 

제대로 TextView의

크기를 구하였습니다


근데 TextView를

Match로 잡았는데

656이 나오네요


그래서 다시 xml를 보니

margin이 잡혀있습니다

margin을 제거해주고

돌려보니 720이

나오는것을 확인하였습니다.


그런데 생각해보면

실행되서 화면이 뿌려지는

순간 TextView의 

Width, Height를 

얻어야 되는 상황이 아니라면

굳이 onWindowFocus에서

구해줄 필요는 없습니다



 그렇다면

 onWindowFocus에서 

구한값을 활용해보기 

위해서

시작과 동시에

TextView에 

값을 뿌려보겠습니다.


public class MainActivity extends ActionBarActivity
{
TextView tv;
int width;
int height;
@Override
protected void onCreate(Bundle savedInstanceState)
{
Log.d("ITPANGPANG", "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

tv.setText("x=>" + width + ",y=>" + height);
}

@Override
public void onWindowFocusChanged(boolean hasFocus)
{
Log.d("ITPANGPANG","onWindowFocusChanged");
tv = (TextView)findViewById(R.id.tv);
width = tv.getWidth();
height = tv.getHeight();
}
}

 

 한 줄 추가했습니다

구한값을 

TextView에 setText

하였습니다.




돌려보면 

알겠지만..

당연히 NullPointer 떨어집니다..

위에서 설명했듯이


onWindowFocusChanged가

그 후에 호출되니까요


이를 해결하기 위해서는

약간의 딜레이만 

추가해주면 해결됩니다.

public class MainActivity extends ActionBarActivity
{
TextView tv;
int width;
int height;
@Override
protected void onCreate(Bundle savedInstanceState)
{
Log.d("ITPANGPANG", "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable()
{
@Override
public void run()
{
tv.setText("x=>" + width + ",y=>" + height);
}
}, 50);


}

@Override
public void onWindowFocusChanged(boolean hasFocus)
{
Log.d("ITPANGPANG","onWindowFocusChanged");
tv = (TextView)findViewById(R.id.tv);
width = tv.getWidth();
height = tv.getHeight();
}

}




후훗

원하는 결과를 

얻었습니다


이제 이것을 활용하면

모든 디바이스에서


동적으로 무언가를

같은 위치에 생성할때

편리하게 사용할 

수 있습니다