스마트기기개발관련/안드로이드 개발

안드로이드 여러해상도 지원, DIP 관련

AlrepondTech 2020. 9. 19. 02:44
반응형

 

 

=================================

=================================

=================================

 

 

 

 

출처: 안드로이드펍

dip 당 pixel 구하기

Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();

int width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 300, dm);
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 300, dm);

 

 

=================================

=================================

=================================

 

 

 


private static final float GESTURE_THRESHOLD_DIP = 16.0f; //상수정의
mGestureThreshold= TypedValue.applyDimension(           //Pixel 변환
TypedValue.COMPLEX_UNIT_DIP,
GESTURE_THRESHOLD_DIP,
getResources().getDisplayMetrics());


상수는항상DIP로정의한후Pixel로변환해사용

private static final float GESTURE_THRESHOLD_DIP = 16.0f; //상수정의
final float scale = getContext().getResources().getDisplayMetrics().density;
mGestureThreshold= (int) (GESTURE_THRESHOLD_DIP * scale + 0.5f);

[안드앱콘] 1.다양한스크린사이즈.pdf
0.58MB



=================================

=================================

=================================

 

 

 



출처: http://cafe.naver.com/aphone.cafe?iframe_url=/ArticleRead.nhn%3Fclubid=17198535%26page=2%26menuid=14%26boardtype=L%26articleid=10671%26referrerAllArticles=false

public int getLcdSIzeWidth() {
    return ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();
}

public int getLcdSIzeHeight() {
    return ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getHeight();
}

 

DisplayMetrics dm = new DisplayMetrics();
_activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;
screenHeight = dm.heightPixels;


위와 같이 해도 해상도를 구할수 있다.

 

 

=================================

=================================

=================================

 

 


출처: http://theeye.pe.kr/entry/display-utility-for-convert-dip-to-pixel-on-android

안드로이드에서는 기본적으로 화면 해상도에 의존적이지 않는 화면 구성을 하여야만 합니다. 하지만 동적으로 UI를 구축한다거나 또는 복잡한 레이아웃에서는 그것이 쉽지가 않죠. 그경우엔 픽셀 단위의 글을 자유자재로 DIP으로 혹은 그 반대로 변환할 수 있어야 합니다. 다음은 간단히 사용할 수 있는 예제입니다.

public class DisplayUtil {
    private static final float DEFAULT_HDIP_DENSITY_SCALE = 1.5 f;
    /**
     * 픽셀단위를 현재 디스플레이 화면에 비례한 크기로 반환합니다.
     * 
     * @param pixel 픽셀
     * @return 변환된 값 (DP)
     */
    public static int DPFromPixel(int pixel) {
        Context context = BaseApplication.getContext();
        float scale = context.getResources().getDisplayMetrics().density;

        return (int)(pixel / DEFAULT_HDIP_DENSITY_SCALE * scale);
    }

    /**
     * 현재 디스플레이 화면에 비례한 DP단위를 픽셀 크기로 반환합니다.
     * 
     * @param  DP 픽셀
     * @return 변환된 값 (pixel)
     */
    public static int PixelFromDP(int DP) {
        Context context = BaseApplication.getContext();
        float scale = context.getResources().getDisplayMetrics().density;

        return (int)(DP / scale * DEFAULT_HDIP_DENSITY_SCALE);
    }
}

 

 

=================================

=================================

=================================

 

 



출처: http://theeye.pe.kr/entry/display-utility-for-convert-dip-to-pixel-on-android

pix → dip 변환 : dips = pixels * (160 / density)
dip → pix 변환 : pixels = dips * (density / 160)

 

http://blog.naver.com/protosi?Redirect=Log&logNo=70108936303

 

public classDisplayUtil {
    private static final float DEFAULT_HDIP_DENSITY_SCALE = 1.5 f;
    /**

                 * 픽셀단위를 현재 디스플레이 화면에 비례한 크기로 반환합니다.

                 * 

                 * @param pixel 픽셀

                 * @return 변환된 값 (DP)

                 */
    public static int DPFromPixel(int pixel) {
        Context context = BaseApplication.getContext();
        float scale = context.getResources().getDisplayMetrics().density;

        return (int)(pixel / DEFAULT_HDIP_DENSITY_SCALE * scale);
    }

    /**

                 * 현재 디스플레이 화면에 비례한 DP단위를 픽셀 크기로 반환합니다.

                 * 

                 * @param  DP 픽셀

                 * @return 변환된 값 (pixel)

                 */
    public static int PixelFromDP(int DP) {
        Context context = BaseApplication.getContext();
        float scale = context.getResources().getDisplayMetrics().density;

        return (int)(DP / scale * DEFAULT_HDIP_DENSITY_SCALE);
    }
}

 

안드로이드 화면 크기 구하기 ( 디바이스 )

import android.util.DisplayMetrics;

DisplayMetrics displayMatrics = new DisplayMatrics();

int height = getWindowManager().getDefaultDisplay().getHeight();
int width = getWindowManager().getDefaultDisplay().getWidth();

 

<가로 고정>

AndroidManifest.xml


android:screenOrientation="portrait"


해당엑티비티.java

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);



<세로 고정>

AndroidManifest.xml


android:screenOrientation="landscape"

해당엑티비티.java

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

 

 

 

=================================

=================================

=================================

 


출처: http://blog.naver.com/protosi?Redirect=Log&logNo=70108936303


안드로이드 어플을 개발하기 위해서는 dip에 대해 알아야 한다.

 

dip은 density-Indefendent Pixel인데, 한마디로 밀도에 독립적인 픽셀이다.

 

보통 1 인치에 160픽셀이 들어가면 160ppi 혹은 160dpi라고 적는데

 

이 160dpi의 값이 Android 개발에 있어서 기준이 되는 HGVA(320*480)값이다.

 

그리고 WVGA이나 FWVGA같은 Gigh Density 240 Hdip도 요즘 나오고 있다.

 

bmp이나 png 같은 그림파일은 당연히 pixel기반이다.

 

때문에 파일 작업을 하려면, Dip <-> Pixel 이 개념이 있어야 한다.

 

 

처음 Dip개념을 샜을 땐 이런 느낌이었다.

 

 

"자! 돌멩이의 갯수를 세봐!!! 단, 1, 2, 3, 4 숫자를 써서는 안 돼!!!"

 

기존의 픽셀 기반을 스면, 좌표가 박살나기 때문이다.

 

 

 

 

 

Mdip(160) HGVA(320*480)의 화면,

 

해상도에 대한 아무런 설정을 하지 않은 상태에서

 

해상도를 올리면 어떻게 될까?

 

 

 

 

 

 

 

그림을 클릭하면 원본크기로 나와 좀더 자세히 볼 수 있다.

 

보면 알겠지만, 해상도가 높아지는 경우

 

좌표가 뭉게진다.

 

옆에 그림은 dip 160 일 때의 그림을 가지고 와서

 

비교한 것...

 

각 카드 그림 당 간격은 동일한 것을 알 수 있다.

 

 

 

즉, 원래 좌표는 그대로인데 카드 그림만

 

확대된 건데

 

dip개념 때문이다.

 

추상화된 pixel개념인데

 

왼쪽 화면과 오른쪽 화면이 1:1이라고 생각하자.

 

물론 pixel값이 다른데 어찌 그럴 수 있느냐 생각하겠지만

 

pixel을 추상화 하는 거다.

 

즉, 동일한 화면 크기에 해상도만 다른

 

두 기종이 있다고 하자.

 

그러면 A기종과 B기종이 보는 그림은

 

pixel은 달라지겠지만,

 

결과적으로 같다. (해상도가 차이는 있겠지만...)

 

 

다시 말하자면, 그림이 확대된 만큼,

 

간격도 확대되어야 한다.

 

dpi가 160에서 240으로 증가하면

 

픽셀 수는 1.5배 많아진다.

 

따라서 픽셀 좌표도 1.5배 많아진다.

 

 

로드된 이미지들은 해상도에 따라

 

어플리케이션이 늘리고 줄이지만,

 

직접적인 픽셀 제어는 모두 dip로의 변환작업을 거쳐야 한다.

 

 

즉, dpi가 120, 160, 240 이 세 값에 따라

 

각각 비율이

 

0.75, 1, 1.5가 되는 것이다.

 

 

원본 이미지를 load하면

 

확대 축소는 위와 같이 저절로 되나

 

간격은 맞추어주어야 한다.

 

즉, 0.75, 1, 1.5값 중 하나를 곱해야 하는데

 

그걸 구하는 구문이 바로

 

final float scale = getResources().getDisplayMetrics().density;

 

이거다.

 

 

 

 

 

 그러면 이렇게 간격이 맞게 나오는 것을 알 수 있다.

 

 

 

이 때, 눈썰미가 좋은 사람이라면 하단에 없던 여백이 생긴 것을 알 수 있다.

 

그 이유는 역시 해상도에 있다.

 

dpi160의 Mdip기반 HGVA는 (320 * 480)필셀이다.

 

이 비율 고대로 해상도를 Hdip까지 올린다면

 

1.5를 곱해야 하니까

 

(480 * 720)이 나온다.

 

근데, Hdip 기반 WVGA는 480*800 이고

 

FWVGA는 480*854이다.

 

즉, 80pixel과 134pixel이 남는 것이다.

 

 

반면 해상도를 120dpi로 낮추면

 

(240 * 320) 비율이 된다.

 

이는 Ldip QVGA (240*320)과 같은데

 

Ldip의 WQVA는 (240*400)이고

 

FWQVGA는 (240*432)임을 알아야 한다.

 

즉, 가로 픽셀 값은 dpi 비율에 따라 변화지만

 

세로 픽셀은 그렇지 않다.

 

따라서 하단의 남는 여유 공간을

 

처리해주어야 한다.

 

앞서 설명한 Scale값을 비교해서

 

0.75 이면 (0, 320)위치에

 

1.5이면 (0, 720) 위치에

 

하단 Bar를 만들어 넣어주는게 좋겠다.


 

=================================

=================================

=================================

 

 



 

 

[출처] [Android] dip와 pixel, 그리고 density|작성자 MiDtics

 


출처: http://kottodat.com/xe/495

scrollview와 lsitview는 함께 사용하면 뷁이된다.

 

scrollview 안에 listview를 넣을 경우 그리고 두놈 다 내용이 스크롤되야 할 만큼 내용이 있을 경우

 

scrollview 안의 listview는 원하는대로 스크롤이 안됩니다.

 

 

이유인 즉슨...

 

어떤녀석을 클릭했는지 알 수가 없어서랍니다.

 

 

 

대충 정리를 해보자면...

 

화면에 내용이 많이 들어갈 경우 스크롤 뷰를 사용합니다.

 

그리고 리스트뷰도 넣어야 할 경우...

 

그리고 리스트뷰 자체의 크기도 늘려버립니다 -_-;

 

 

 

 

 

위 그림과 같이 스크롤 뷰의 사이즈 자체를 늘려버릴 경우 모든 내용이 보이게 되고 ListView는 스크롤이 생기지 않고

 

ScrollView만 스크롤뷰가 생겨서 모든 내용을 볼 수 있습니다.

 

물론 이 방법이 마음에 들지 않는 분도 계시겠지만 뭐...

 

저는 이렇게 처리해서 일을 했습니다.

 

 

 

참고로 리스트 뷰의 사이즈를 조절하는 방법은 아래와 같습니다.

 

/// XML작업할땐 dip로 넣고 코드에선 pixal단위로 작업하기 때문에 1dip가 몇 pixal인지 알아내야함

 

float m_dipScale ; /// 변수 선언

 

/// 1dip가 몇 pixal인지 구하는 구문

m_iScale = this.getResources( ).getDisplayMetrics( ).density ;

 

/// (아이템 갯수 * 아이템 사이즈 * m_iScale + 아이템갯수 - 1 )

lv.getLayoutParams().height = (int) ( ItemCount  * ItemSize * m_Scale + ItemCount - 1 )  ;

 

 

아이템의 높이가 30 그리고 갯수가 50일 경우

 

아이템 하나마다 30의 높이를 차지하고 50개의 아이템 사이에 경계션으로 49개의 1픽셀짜리 라인이 들어갑니다.

 

그런고로

 

아이템의 총 높이 = 갯수 * 높이 * dip

경계선 = 아이템 갯수 - 1

 

리스트뷰 크기 = 아이템의 총 높이 + 경개션이 차지하는 픽셀

 

이렇게 넣어주면 됩니다.

 

 

주의사항이라면

 

inflater로 삽입하는 xml파일의 최상위 레이아웃의 사이즈는 무시되니까 그놈은 그냥 wrap_content로 줘버리고

 

그안에 레이아웃을 하나 더 만들어서 사이즈를 지정해 줘야 제대로 먹습니다.



=================================

=================================

=================================

 

 


출처: http://snowbora.com/422

[안드로이드] 화면 해상도에 관계없는 레이아웃(Layout) 만들기

개발자 이야기/안드로이드 2011/06/29 17:11

 

안드로이드로 개발하다보면 xml 파일을 이용해서 레이아웃(Layout)을 설정하고 그 안에서 코드를 작성하는 경우가
대다수일겁니다. 

이 때, 각 뷰(View)들의 좌표나 폭, 높이 등을 설정하는데, 픽셀 좌표인지, 밀도 좌표인지 기타 또 다른 좌표계인지에
따라 그 값이 바뀌게 됩니다. 또한 해당 어플리케이션을 실행시킬 단말기의 스크린 크기나 해상도에 따라 
화면이 어색하게 나오거나 심한 경우에는 깨진 화면이 나타나기도 합니다. 

저는 480x800의 해상도를 가진 갤럭시S2와 600x1024의 해상도를 가진 갤럭시탭 7인치 모델을 동시에 사용해서
개발하다보니 서로의 GUI 화면 좌표가 다르게 표시되는 현상이 발생해버렸습니다.

별의별 수단을 써봤습니다. 픽셀 좌표인 px를 사용해서 값을 지정해보기도 했고,
밀도 좌표인 dip나 dp를 사용해보기도 했습니다. 


여기서 잠깐!! px와 dp에 대해서 먼저 정리하고 넘어가겠습니다.

 

안드로이드는 160dpi를 기본으로 가정하고 있습니다. 이때 화면 해상도는 320x480이 됩니다.
해상도 320x480에서 가로폭이 160dp가 되기 때문에, 1dp의 크기는 320 / 160 = 2 pixel이라고 볼 수 있습니다.

하지만 요즘 단말기들의 해상도들은 WVGA인 480x800의 단말기가 많습니다.
픽셀 좌표를 이용해서 320x480 단말기에서 GUI를 구성하면 480x800인 단말기에서는 작은 화면으로 출력이 되고,
그 반대로 480x800에서의 GUI를 320x480인 단말기에서 출력하면 GUI가 잘려서 보여지게 됩니다.
심한 경우에는 깨진 GUI를 보이기도 하죠.

이 때를 대비해서 만든 것이 dip(density independent pixel) 단위입니다.
화면의 픽셀 밀도를 정의해서 만든 단위이기 때문에 같은 dip 값을 이용해서 레이아웃을 작성하면 
어느 해상도를 가진 단말기라고 하더라도 같은 비율로 이루어진 GUI 화면을 보여주게 됩니다. 
즉, 화면 해상도에 관계없는 균일한 GUI를 제공하는 어플리케이션을 제공할 수 있는거죠.

안드로이드에서 간주하고 있는 해상도 범주는 크게 3가지 입니다.
LDPI(저해상도), MDPI(중해상도), HDPI(고해상도) 이며, 각각의 밀도값은 LDPI가 120, MDPI가 160, HDPI가 240입니다.
(인치당 픽셀수를 의미합니다.)

 



그리고 픽셀 좌표와 dip 좌표의 환산공식은 다음과 같습니다.

 

dip = px * (160 / density)

 

안드로이드가 160dpi를 기준으로 하고 있기 때문에 위와 같은 공식이 나오는 것이며,


만약 해상도 480x800 단말기에서 이런 수식을 계산하게 된다면, 480x800은 고해상도인 HDPI이기 때문에

 

480x800 해상도에서 dip와 px 단위 환산
 

dip = px * (160/240) = px * (2/3)

 

이 됩니다. 따라서 480x800 px 좌표는 320x533 dip 좌표라고 생각하면 됩니다. 




하지만 !!!
이렇게 px나 dip만을 이용해서 모든 해상도를 고려한 레이아웃이 술술술 나온다면 얼마나 좋겠습니까?
저도 갤럭시S2와 갤럭시탭7인치를 갖고 개발하다가 큰 난관에 봉착하게 되었는데
이 녀석들이 같은 dpi를 가지고 있는 겁니다. 화면 해상도는 480x800과 600x1024인데 dpi는 둘 다 240dpi입니다.

즉, 갤럭시S2에 맞게 GUI를 구성하면 갤럭시탭에서 깨진 GUI를 보여주게 되더군요.


결국, 이런 저런 문제 해결을 고려하다가 레이아웃에서 가중치(weight)값을 이용해서 화면을 구성하는 방법을 택하게 되었습니다.
어제 하루종일 px와 dip를 갖고 고민을 했지만, weight를 이용하니 고민이 한번에 날아갔습니다. +_+

 

 


만약 이와 같은 GUI를 구성한다고 할 때, 레이아웃은 다음과 같이 작성하면 됩니다.
아무 것도 없는 공간에 LinearLayout을 이용해서 공간을 할당하는게 키포인트입니다.


샘플 xml 코드는 다음과 같습니다. 

 

<?xml version="1.0" encoding="utf-8"?>

   

<LinearLayout

android:orientation="horizontal"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:layout_gravity="center"

        android:background="@drawable/player_landscape_bg_control">

 

    <LinearLayout  

        android:layout_width="0px" 

        android:layout_height="fill_parent"

        android:layout_weight="175"/>

    

<ImageButton

android:id="@+id/btnImgP_ZoomOut"

android:layout_width="0px" 

             android:layout_height="wrap_content"

             android:layout_weight="83"

             android:background="@drawable/photoviewer_btn_zoom_out_landscape"/> 

    

    <LinearLayout  

       android:layout_width="0px" 

       android:layout_height="fill_parent"

       android:layout_weight="40"/>

 

    <ImageButton

android:id="@+id/btnImgP_PlayAndPause"

android:layout_width="0px" 

         android:layout_height="wrap_content"

         android:layout_weight="83"

         android:background="@drawable/photoviewer_btn_play_landscape"/> 

   

<LinearLayout  

       android:layout_width="0px" 

       android:layout_height="fill_parent"

       android:layout_weight="30"/>

 

    <ImageButton

android:id="@+id/btnImgP_ZoomIn"

android:layout_width="0px" 

         android:layout_height="wrap_content"

         android:layout_weight="83"

         android:background="@drawable/photoviewer_btn_zoom_in_landscape" />

    

    <LinearLayout  

       android:layout_width="0px" 

       android:layout_height="fill_parent"

       android:layout_weight="40"/>

    

    <ImageButton

android:id="@+id/btnImgP_ChangeDMR"

android:layout_width="0px" 

         android:layout_height="wrap_content"

          android:layout_weight="83"

         android:background="@drawable/photoviewer_btn_changedisplay_landscape" />

    

    <LinearLayout  

       android:layout_width="0px" 

       android:layout_height="fill_parent"

       android:layout_weight="183"/>

 

</LinearLayout>

 

샘플은 가로 방향의 빈 공간에 대해서만 가중치를 줬지만 weight는 가로든 세로든 어디에나 적용할 수 있습니다.


그리고 무사히 갤럭시S2와 갤럭시탭에서 같은 화면을 보여줄 수 있게 되었습니다.
편하게 사용하려고 만든 dip 단위가 참 쓸모가 없다라는걸 느꼈던 순간이네요. -_-;;


=================================

=================================

=================================

 

 


출처: http://overoid.tistory.com/10


1번 이미지는 앱의 정보를 볼 수 있는 이미지 버튼 스타일의 ImageView 입니다. (디퐅트 이미지:info.png, 클릭 이미지:info_clicked.png) 클릭시 팝업 대화상자가 나타날 겁니다. 디폴트로 회색 이미지였다가 클릭시 배경색이 블루로 변경됩니다. . 이 이미지는 iconWorkshop에 있는 이미지를 32*32로 맞추고, grayscale로 변환하여 회색 배경의 이미지로 만들었습니다.

 

Android에서 클릭시 이미지를 변경되는 효과를 주기 위해서 물론 코딩으로도 처리할 수 있지만, xml로 간단히 구현할 수 있습니다. 아래 코드처럼 xml 문서를 만드신 후 drawable 디렉토리에 저장합니다.

 

button_info.xml

 

<?xml version="1.0" encoding="utf-8"?>

 

    <item android:state_focused="true"

android:state_pressed="false"

android:drawable="@drawable/info_clicked" />

    <item android:state_focused="true"

android:state_pressed="true"

android:drawable="@drawable/info_clicked" />

    <item android:state_focused="false"

android:state_pressed="true"

android:drawable="@drawable/info_clicked" />

    <item android:drawable="@drawable/info"/>

</selector>

 

 

Selector element 하위에 item element가 들어갑니다. Item element의 attribute를 보시면 다음의 4가지로 나누어져 있습니다. 
android:state_focused="true" android:state_pressed="false" 포커스를 가지고 있으면서 누르지 않은 상태.(보통 클릭 후 상태) 
android:state_focused="true" android:state_pressed="true" 포커스를 가지고 있으면서 누른 상태 android:state_focused="false" android:state_pressed="true" 포커스는 없으면서 누른 상태 아무런 속성 설정이 없는 것은 디폴트 상태. 입니다. 

Custom EditText 같은 경우에는 위 4가지 속성에 따라서 배경이미지를 다르게 줄 수 있으나, 저희는 클릭시에만 다른 이미지를 보여 줄 것이므로, 디폴트 상태값에는 info.png를 할당하고, 나머지 클릭 상태값에는 info_clicked.png를 설정했습니다. 
그림에서 4번 이미지와 5번 이미지는 clipboard copy 및 record delete를 위한 버튼(이미지)입니다. 버튼 클릭시 배경색을 주황색으로 바꿔 주도록 효과를 주기 위해서 이미지를 제작하신 후 button_info.xml과 동일한 스타일로 xml 문서를 만들어 drawable 디렉토리에 저장합니다. 

button_copy_clipboard.xml

 

<?xml version="1.0" encoding="utf-8"?>

 

    <item android:state_focused="true"

android:state_pressed="false"

android:drawable="@drawable/copy_clipboard_clicked" />

    <item android:state_focused="true"

android:state_pressed="true"

android:drawable="@drawable/copy_clipboard_clicked" />

    <item android:state_focused="false"

android:state_pressed="true"

android:drawable="@drawable/copy_clipboard_clicked" />

    <item android:drawable="@drawable/copy_clipboard" />

</selector>

 

 

button_delete_record.xml 

 

<?xml version="1.0" encoding="utf-8"?>

 

    <item android:state_focused="true"

android:state_pressed="false"

android:drawable="@drawable/delete_record_clicked" />

    <item android:state_focused="true"

android:state_pressed="true"

android:drawable="@drawable/delete_record_clicked" />

    <item android:state_focused="false"

android:state_pressed="true"

android:drawable="@drawable/delete_record_clicked" />

    <item android:drawable="@drawable/delete_record" />

</selector>

 


다음은 6번 이미지를 위한 xml을 보도록 하겠습니다. 저희 앱에 구지 필요 없는 항목이긴 하지만, UI를 좀 더 미려하게 보이게 하기 위해서 추가했습니다. 코드는 다음과 같습니다. 

shape_title_indicator.xml

 

<?xml version="1.0" encoding="UTF-8"?> 

 

    <stroke android:width="2dip"  android:color="#19CD00" />

    <corners android:bottomRightRadius="1dip" android:bottomLeftRadius="1dip" 

             android:topLeftRadius="1dip" android:topRightRadius="1dip"/> 

    <padding android:left="1dip" android:top="1dip"

             android:right="1dip" android:bottom="1dip" />

</shape>

 

 


이 코드는 기본 도형들을 xml로 정의하는 방법입니다. Shape를 line으로 지정하여 선을 만들수도 있으며 oval 로 지정하여 타원형을 만들수도 있습니다. 

 

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">

   <stroke android:width="1dp" android:color="#FF000000"

           android:dashWidth="1dp" android:dashGap="2dp" />

</shape>

 

 

 

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">

    <solid android:color="#00000000"/>

    <stroke android:width="4dp" android:color="#99000000"

            android:dashWidth="4dp" android:dashGap="2dp" />

    <padding android:left="7dp" android:top="7dp"

             android:right="7dp" android:bottom="7dp" />

    <corners android:radius="4dp" />

</shape>

 


Stroke 는 테두리를 그리는 것을 말합니다. dashWidth와 dashGap은 점선을 그릴 때 사용합니다.
Solid는 단색으로 채워 넣는 것을 말하며, gradient는 단색대신 그라디언트 효과를 줄 수도 있습니다 

 

<gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF"

.        android:angle="270"/>

 


Corners는 가장자리를 둥글게 처리하는 것을 말합니다. Padding은 안쪽 여백을 주는 것입니다. 저희 코드가 이해가 가십니까? 저희 코드는 두께가 2dip인 둥근 사각형입니다. 여백을 주었기 때문에 ImageView 사이즈보다 약간 작게 나오게 됩니다. 그래야 우측 텍스트와 크기를 비슷하게 맞출수 있어서 패딩으로 조정했습니다. 실제 ImageView에 xml을 할당할 때 width를 4dip밖에 주지 않을 것이므로 두꺼운 모서리가 둥근 직선으로 보이게 됩니다. 


다음은 문자열을 편집하도록 하겠습니다. Motodev에서 res/values/string.xml 파일을 더블 클릭하여 엽니다. 아래 그림과 같이 편집합니다.

 

 

 

 

 


Motodev를 사용하기 때문에 여러 언어를 표 형태의 편집창에서 바로 편집할 수 있어서 편리합니다. 문자열 입력값은 XML 문서 안에 정의되므로 XML 문법에 허용되지 않는 문자열은 입력하시면 에러가 납니다. 저희 앱의 Info 팝업창을 만들 때(뒤쪽 편에 있습니다.) 엔터가 들어간 긴 문장을 TextView에 표시하기 위해서 xml에 문자열 값을 CDATA 섹션에 넣어서 처리를 해 보려고 했으나 제대로 처리가 되지 않았습니다. 특수문자들은 CDATA 안에 넣어서 처리할 수 있습니다. 엔터가 들어간 여러줄의 텍스트를 표현하려면 아직 제가 해본 바로는 각각의 문장을 문자열로 만들어서 프로그램에서 Html.fromHtml() 메소드 처리시 문장마다 <br/>태그를 넣어주거나, 레이아웃에서 여러 개의 TextView를 만들어 사용하시는 것도 한가지 방법입니다. 

그리고 label_title_main의 값처럼 <u><b>태그를 추가하여 타이틀 텍스트에 밑줄과 볼드체효과를 줄 수 있습니다. <u><b><i>태그값은 string의 value값으로 바로 정의할 수 있습니다. 

이제 drawable에 들어갈 항목을 모두 정의했습니다. 이제부터 메인 레이아웃을 작성하도록 하겠습니다. 프로젝트 생성시 자동으로 만들어진 res/layout/main.xml 파일을 열어서 다음과 같이 편집합니다. 

Main.xml 

 

<?xml version="1.0" encoding="utf-8"?>

 

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

         <!-- 상단 타이틀바 -->                     

         <LinearLayout android:layout_width="fill_parent"

                       android:layout_height="wrap_content"

                       android:orientation="horizontal"

                       android:background="@drawable/layout_box_bg">

                  <ImageView android:layout_width="4dip"              

                             android:layout_height="20dip"

                             android:layout_marginLeft="3dip"

                             android:layout_gravity="center_vertical"

                             android:src="@drawable/shape_title_indicator"/>

                                                       

                  <TextView android:layout_width="fill_parent"

                           android:layout_height="wrap_content"

                           android:layout_marginLeft="6dip"

                           android:layout_gravity="center_vertical"

                           android:layout_weight="1"

                           android:paddingTop="4dip"

                           android:paddingBottom="2dip"

                           android:textColor="#FFFFFF"

                           android:textSize="16sp"

                           android:text="@string/label_title_main"/>  

                                  

                  <ImageView android:id="@+id/button_info"

                           android:layout_height="32dip"

                           android:layout_width="32dip"

                           android:layout_gravity="right|center_vertical"

                           android:background="@null"

                           android:src="@drawable/button_info"/>                                 

                                                          

         </LinearLayout>

        

         <!-- 상단 한글/영문 입력창  -->

         <LinearLayout android:layout_width="fill_parent"

                       android:layout_height="wrap_content"

                       android:orientation="vertical"

                       android:background="@drawable/layout_box_bg_large">

                       

                  <LinearLayout android:layout_width="fill_parent"

                                android:layout_height="wrap_content"

                                android:orientation="horizontal"  >

                           <TextView android:layout_width="55dip"

                                     android:layout_height="wrap_content"

                                      android:layout_gravity="center_vertical"

                                     android:layout_marginLeft="10dip"

                                     android:textColor="#FFFFFF"

                                     android:textSize="16sp"

                                     android:text="@string/label_password"/>

                           <EditText android:id="@+id/text_password"

                                     android:layout_width="wrap_content"

                                     android:layout_height="38dip"

                                     android:textSize="12sp"

                                     android:layout_weight="1"/>

                           <ImageButton android:id="@+id/button_remove"

                                   android:layout_height="38dip"

                                   android:layout_width="38dip"

                                    android:scaleType="centerCrop"

                                   android:layout_marginLeft="3dip"

                                   android:layout_gravity="right"

                                 android:src="@drawable/remove"/>                                                                  

             </LinearLayout>           

             

             <LinearLayout android:layout_width="fill_parent"

                           android:layout_height="wrap_content"

                           android:orientation="horizontal" >

                          

<TextView android:layout_width="55dip"

                                      android:layout_height="wrap_content"

                                      android:layout_gravity="center_vertical"

                                      android:layout_marginLeft="10dip"

                                      android:textColor="#FFFFFF"

                                      android:textSize="16sp"

                                      android:text="@string/label_english"/>

 

                           <EditText android:id="@+id/text_english"

                                      android:layout_width="wrap_content"

                                      android:layout_height="38dip"

                                     android:textSize="12sp"

                                     android:layout_weight="1"

                                              />

                      <ImageButton android:id="@+id/button_copy"

                                   android:layout_height="38dip"

                                   android:layout_width="38dip"

                                   android:scaleType="centerCrop"

                                   android:layout_marginLeft="3dip"

                                   android:layout_gravity="right"

                                   android:src="@drawable/copy"/>             

             </LinearLayout>                     

         </LinearLayout>

        

         <Button android:id="@+id/button_save"

                 android:layout_width="fill_parent"

                 android:layout_height="wrap_content"

                 android:layout_marginTop="4dip"

                 android:drawableLeft="@drawable/save"

                 android:gravity="center"

                 android:text="@string/save"/>       

                

         <!-- list Layout -->

         <LinearLayout android:orientation="vertical"

                  android:layout_width="fill_parent"

                  android:layout_height="fill_parent"

                  android:background="@null"

                  android:layout_weight="1">

                          

                  <ListView android:id="@+id/android:list"

                           android:layout_width="fill_parent"

                           android:layout_height="fill_parent"

                           android:drawSelectorOnTop="false"/>

        

                  <TextView android:id="@+id/list_empty"

                           android:layout_width="fill_parent"

                           android:layout_height="fill_parent"

                           android:gravity="center_horizontal|center_vertical"

                           android:textSize="20sp"

                           android:paddingTop="50dip"

                           android:text="" />

        

         </LinearLayout>           

</LinearLayout>

 

 

 

반응형

 

728x90

 



LinearLayout만을 사용하여 UI 요소들을 배치했습니다. 

상단 타이틀바 영역을 보시면 가운데 TextView 항목만 android:layout_weight="1" 로 주어졌습니다.  화면이 커지고 작아졌을 때 가운데 TextView만 가중치를 주어 늘어나고 줄어들도록 처리했습니다. 다른 부분들도 마찬가지입니다.

 

하단의 리스트뷰 정의 부분을 보시면 <ListView android:id="@+id/android:list" 아이디를 설정하는 부분이 다른 것과 좀 다릅니다. 저희는 메인 화면에 리스트가 들어갈 것이고, 코딩을 좀 더 간단히 처리하기 위해서 ListActivity에서 상속받을 것입니다. ListActivity에서 상속을 받아서 리스트 처리를 할 때는 반드시 아이디를 위와 같이 기술하셔야 합니다.

 

나머지 레이아웃 소스는 그 동안 책을 보셨다면 대부분 아실 내용입니다. 책을 안 보셨더라도 속성명만 가지고도 대충 알 수 있을 겁니다. 저는 여기서 상세한 설정 정보에 대해서 설명하기 보다는 ImageView  ImageButton의 사이즈 설정에 대해서 애기를 좀 하겠습니다.

 

먼저 레이아웃 소스 중 타이틀영역의 Info 버튼 이미지 부분 입니다.

 

<ImageView android:id="@+id/button_info"

           android:layout_height="32dip"

           android:layout_width="32dip"

           android:layout_gravity="right|center_vertical"

           android:background="@null"

           android:src="@drawable/button_info"/>

 


ImageView 
사이즈가 가로, 세로 모두 32dip 입니다. 
저희 이 info 이미지를 hdpi 폴더에 48*48 크기로 만들어 두었습니다. ImageView src 속성에 지정되는 이미지는 로딩시에 pre-scaling이 됩니다.  hdpi 폰 에서는 저희가 만들어둔 hdpi 폴더의 이미지 사이즈 그대로 48*48 크기의 이미지가 로딩되며, mdpi에서는 48/1.5 = 32 , 32*32 크기 이미지로 축소되어서 로딩됩니다. 그리고 ImageView가 화면에 그려질 때 scaleType 속성값에 지정된 값에 따라서 다시 스케일이 조정될 수도 있지만, scaleType을 지정하지 않으면 디폴트값이 center 속성값이 지정됩니다. center는 따로 스케일 조정을 하지 않는 옵션이므로 ImageView에는 저희가 계획한대로 hdpi에서는 48*48 크기로, mdpi에서는 32*32 크기로 이미지가 화면에 그려집니다.


다음은 ImageButton 부분 최종 소스입니다.

 

<ImageButton android:id="@+id/button_copy"

             android:layout_height="38dip"

             android:layout_width="38dip"

             android:scaleType="centerCrop"

             android:layout_marginLeft="3dip"

             android:layout_gravity="right"

             android:src="@drawable/copy"/>

 

 

 

ImageButton 이게 골 때리는 겁니다. ImageView는 우리가 원하는 대로 정확하게 동작합니다. 하지만 이미지 버튼은 그렇지가 않습니다.

 

먼저 아래의 소스를 보겠습니다. 최종 소스와 다른 점은 ImageButton View의 가로 세로사이즈가 32dip이며 scaleType을 지정하지 않았기 때문에 center 값으로 동작합니다. , 이미지를 draw할 때 별다른 scale 작업을 하지 않습니다. 저희가 이 ImageButton에 사용할 아이콘을 Info icon과 동일하게 hdpi 폴더에 48*48 사이즈로 만들어 두었습니다.

 

32*32 size ImageButton의 레이아웃을 설정했을 때.

 <ImageButton android:id="@+id/button_copy"

             android:layout_height="32dip"

             android:layout_width="32dip"

             android:layout_marginLeft="3dip"

             android:layout_gravity="right"

             android:src="@drawable/copy"/>

 


ImageView
와 동일한 방식으로 쉽게 생각하여 hdpi 화면에서 48*48 사이즈로 이미지를 로딩하면

 

 

 

 

 

~ 이 이미지처럼 버튼 형태의 디자인보다 이미지가 더 커져 버립니다.

 

왜 이럴까요? 버튼의 경우에는 버튼처럼 보이게 하기 위해서 버튼 배경 이미지가 뒤에 깔립니다. 그래서 이런 모습으로 보입니다. 버튼을 나타내는 ImageButton View의 크기를 우리가 제작한 이미지 보다 크게 그려야 합니다. 참고로 이미지 버튼 xml 설정값에서 android:background="@null" 이라고 설정을 추가하면 ImageButton의 버튼 배경이미지가 없어지고, ImageView와 동일한 형태가 되어 버립니다.

 

아래 코드는 위의 단점을 보완하기 위해서 scaleType은 설정하지 않고 ImageButton의 크기만 키웠습니다. 어찌 될까요?

 

<ImageButton android:id="@+id/button_copy"

             android:layout_height="38dip"

             android:layout_width="38dip"

             android:layout_marginLeft="3dip"

             android:layout_gravity="right"

             android:src="@drawable/copy"/> 

 

 

 

 

 

 

좀 낫습니다. 그래도 너무 꽉 차 보이는 군요. 제가 원하는 바는 아닙니다. 그렇다면 ImageButton의 경우 내부에 그림이 그려질 정확한 영역은 얼마일까요? 아래 그림은 WVGA800 화면의 내용을 Android SDK Tools 폴더 하위에 있는 hierarchyviewer.bat 툴로 살펴본 모습니다. 해당 ImageButton을 클릭해보니 width, height값이 57(우리가 Layout에서 38dip를 지정했고, hdpi 모드에서는 38 * 1.5 = 57이 됩니다)이며, padding 값이 mPaddingBottom=17, mPaddingTop=10, mPaddingLeft=16, mPaddingRight=17 값으로 나타납니다. 

 

 

 

 

 

좀 알기쉽게 그림으로 나타내면 다음과 같습니다. 

 

 

 

 

 

 

물론, 이것도 저희가 원하는 바는 아닙니다. 다음은 scaleType=”centerCrop” 로 설정한 소스입니다.

 

<ImageButton android:id="@+id/button_copy"

             android:layout_height="38dip"

             android:layout_width="38dip"

             android:scaleType="centerCrop"

             android:layout_marginLeft="3dip"

             android:layout_gravity="right"

             android:src="@drawable/copy"/>

 

 

scaleType=”centerCrop”은 이미지(아이콘)를 중앙에 그릴영역 (30 * 24) 에 맞춘 후 원 이미지의 비율에 맞게 가로(24px) 30px로 늘립니다.(minus padding). 아래 그림과 같이 57 * 57 ImageButton 30*30 아이콘이 생성됩니다. 거의 우리가 원하는 디자인이 된 것 같습니다.

 

 

 

 

 

이밖에 scaleType에 대한 다른 옵션에 대한 상세 내용들은 레퍼런스들을 참고하시기 바랍니다.

 

결론적으로 ImageButton에 아이콘을 올릴 경우 다음과 같은 전략을 사용하실 수 있습니다.

 

1. ImageButton View의 사이즈를 38*38 mdpi 기준 레이아웃에서 설정했을 때 res/drawable-hdpi/ 폴더에 30*30 아이콘을 제작해서 넣어둔 후, scaleType를 지정하지 않고(Default : center) 아이콘을 로드하면 pre-scaling 만으로 ImageButton을 그려 넣기 때문에 편리합니다. (32*32로 만들어서 넣어 두어도 보기에 괜챦습니다.)

 

2. 우리 소스처럼 scaleType=”centerCrop”으로 설정하여 보기 좋게 만듭니다. 이 방식은 pre-scaling 이후 draw 시점에 auto-scaling을 한 번 더 하므로 약간의 성능에서 손실을 보지만, 이미지도 몇 개 안되고..크게 무리는 없을 것 같습니다. 저희는 이미 30*30 아이콘이 아닌 48*48로 만들었기 때문에 2번 방식을 사용하도록 하겠습니다.

 

List row Layout

 

다음은 리스트 중 하나의 Item에 대한 레이아웃에 대한 이미지 입니다

 

 

 

 

 

 

위 그림에서 보듯이 list가 단 하나의 항목만 가진게 아니라 여러 항목을 가지고 있다면 별도의 layout을 만들어 adapter에서 처리하는 게 편리합니다. 위 그림을 표현하기 위해 간단하게 레이아아웃을 만들면 다음과 같습니다.

 

아래와 같이 소스를 작성하여 res/layout/ 폴더에 넣습니다.


list_item.xml

 

 

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

           xmlns:android="http://schemas.android.com/apk/res/android"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content">

         <LinearLayout android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:orientation="vertical"

                    android:gravity="left"

                    android:layout_weight="1">

                  <TextView android:id="@+id/korText"

                           android:layout_width="fill_parent"

                           android:layout_height="wrap_content"

                           android:textColor="#FFFFFF"

                           android:textSize="18sp"

                           android:gravity="center_vertical"

                           android:paddingLeft="5dip"

                           android:singleLine="true"/>

         <TextView android:id="@+id/engText"

                           android:layout_width="fill_parent"

                           android:layout_height="wrap_content"

                           android:textColor="#FFF123"

                           android:textSize="20sp"

                           android:gravity="center_vertical"

                           android:paddingLeft="5dip"

                           android:singleLine="true"/>                

                 

    </LinearLayout>

   

    <ImageView android:id="@+id/copyClipboard"

                              android:layout_width="48dip"

                              android:layout_height="48dip"

                              android:layout_marginLeft="5dip"

                              android:layout_marginRight="0dip"

                              android:background="@null"

                              android:src="@drawable/button_copy_clipboard"

                              android:gravity="center_vertical"/>

                             

    <ImageView android:id="@+id/deleteImage"

                              android:layout_width="48dip"

                              android:layout_height="48dip"

                              android:layout_marginLeft="0dip"

                              android:layout_marginRight="0dip"

                              android:background="@null"

                              android:src="@drawable/button_delete_record"

                              android:gravity="center_vertical"/>

</LinearLayout>

 

 

 

모 특별한 내용은 없는 것 같아서 소스에 대한 설명은 생략합니다.

 

끝으로 첫번째 레이아웃 이미지에서 Info(1) 버튼 클릭시 아래 그림과 같이 AlertDialog 를 띄울 예정입니다.

 

 

 

 

 

 

alertDialog 화면을 구성할 때 message(단순문자열)말고 view 자체를 add 할 수가 있습니다.  Information 화면은 다른 App을 만들 때도 거의 유사한 형태로 사용될 수 있는 재사용성이 높은 UI라서 Layout 뿐만 아니라 string 정보도 별도로 xml을 구성하도록 하겠습니다. 일부 개발자 분들 중 문자열 리소스는 res/values/strings.xml 파일에만 작성해야만 되는 줄로 알고 계신 분들도 많은 것 같은데..꼭 그렇지는 않습니다. stings.xml 과 동일한 형식으로 xml 문서를 만드신 후 /res/values/폴더에 다른 이름으로 저장하시면 됩니다. 앱의 복잡도가 올라가면서 문자열 리소스에 등록한 문자열이 많은 경우에 한 파일로만 작성하시면 관리하기 힘이 듭니다. 모듈별로 만드는 것도 나쁘지 않다고 봅니다.

 

저희 앱의 Info 는 앞에서 얘기했듯이 재사용성이 높으므로 stings-info.xml 문서를 만들어 values/ 폴더와 values-ko/ 폴더에 넣습니다.

 

res/values/strings_info.xml

 <?xml version="1.0" encoding="utf-8" standalone="no"?>

<resources>

         <string name="msg_info_desc">Hangul to English is utility app for converting fro hangul keyboard to english keyboard.</string>

    <string name="msg_info_support_email_desc">Support Email </string>

    <string name="msg_info_support_email">jinook@paran.com</string>

    <string name="msg_info_thanks">Thanks.</string>

    <string name="msg_info_support_url">http://overoid.tistory.com</string>

    <string name="msg_info_support_url_desc">Support Site</string>

    <string name="msg_info_close_button">close</string>

</resources>

 


res/values-ko/strings_info.xml

 

<?xml version="1.0" encoding="utf-8" standalone="no"?>

<resources>

         <string name="msg_info_desc">Hangul To English 프로그램(App)은 사용자가 보다 한글로 입력된 패스워드에 해당되는 영문자를 쉽게 찾아주는 앱입니다.</string>

    <string name="msg_info_support_email_desc">문의사항, 건의사항은 이메일로 보내주세요.</string>

    <string name="msg_info_support_email">jinook@paran.com</string>

    <string name="msg_info_thanks">감사합니다.</string>

    <string name="msg_info_support_url">http://overoid.tistory.com</string>

    <string name="msg_info_support_url_desc">상세 메뉴얼 및 프로그램 관련 정보는 아래 사이트를 참고해 주시기 바랍니다.</string>

    <string name="msg_info_close_button">닫기</string>

</resources>

 
그리고 AlertDialog에 넣을 View의 내용을 Layout 파일로 만들어 res/layout/ 폴더에 넣어둡니다.
코딩은 차차 하게 될 것입니다.

res/layout/info.xml

 

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

           xmlns:android="http://schemas.android.com/apk/res/android"

           android:layout_width="fill_parent"

           android:layout_height="fill_parent"

           android:padding="10dip"

           android:orientation="vertical">

          

           <TextView android:layout_width="fill_parent"

              android:layout_height="wrap_content" 

              android:textSize="12sp"

              android:text="@string/msg_info_desc"/>

             

          <TextView android:layout_width="fill_parent"

              android:layout_height="wrap_content" 

              android:layout_marginTop="20dip"

              android:textSize="12sp"

              android:text="@string/msg_info_support_url_desc"/>

          <TextView android:layout_width="fill_parent"

              android:layout_height="wrap_content" 

              android:textSize="12sp"

              android:linksClickable="true"

              android:autoLink="web"

              android:clickable="true"

              android:text="@string/msg_info_support_url"/>

             

          <TextView android:layout_width="fill_parent"

              android:layout_height="wrap_content" 

              android:layout_marginTop="20dip"

              android:textSize="12sp"

              android:text="@string/msg_info_support_email_desc"/>

          <TextView android:layout_width="fill_parent"

              android:layout_height="wrap_content" 

              android:textSize="12sp"

              android:linksClickable="true"

              android:autoLink="email"

              android:clickable="true"

              android:text="@string/msg_info_support_email"/> 

             

          <TextView android:layout_width="fill_parent"

              android:layout_height="wrap_content" 

              android:layout_marginTop="20dip"

              android:textSize="12sp"

              android:text="@string/msg_info_thanks"/>                  

          

</LinearLayout>

 

 

 

LinearLayout 하위에 TextView만 잔뜩 가지고 있는 Simple View입니다. 중간에 제 블로그 및 email 링크를 위해 몇가지 속성이 추가되었습니다. Android:autoLink email 혹은 web으로 주면 자동으로 링크가 만들어집니다. 또한, android:linksClickable=”true”로 설정하시면 앱 화면에서 링크를 클릭하면 자동으로 웹사이트로 이동하거나 이메일 어플이 실행됩니다. 별다른 코드도 필요없습니다.

 

아래 그림은 최종적으로 만든 layout을 별도의 코딩없이 애뮬에 띄운 모습입니다.

 

 


 

                               [HVGA , 영문 모드에서 실행한 화면]

 

 

 

 

 


                              [WVGA800, 한글 모드에서 실행한 화면]


드디어 장문의 레이아웃편이 끝이 났습니다. 파트2에 Syntax Highlight 적용하는데.. 이상하게 먹어서 결국은 다시 빼 버렸네요. 에구..시간만 허비했습니다. 어차피 소스 파일로 제공할 건데...왜 적용하느라 애 먹었는지 ...

리소스편까지 작업된 소스 파일입니다. 필요하신 분 다운받아 가시기 바랍니다.

 

Hangul2English.zip
0.15MB

 

 

 

다음번 강좌에서는 리소스 XML 을 들여다 보는 방법에 대해서 간단히 알려드린 후 DB(sqlite)로 넘어가도록 하


 

 

=================================

=================================

=================================

 

 



출처: http://www.slideshare.net/mosaicnet/-5187233

다양한 모바일에서의 호환성 보장과 사이즈 지원 방법 - Presentation Transcript

  1. 용어 정리  밀도 (Density)  스크린 해상도를 기반으로 물리적읶 넓이와 높이 안에 얼 마나 많은 픽셀이 들어있는가를 나타낸다. Lower density의 스크린에서는 같은 넓이와 높이 안에 더 적은 수의 픽셀이 있고, higher density의 스크린에서는 같은 넓이와 높이 안 에 더 많은 수의 픽셀이 있다. 안드로이드는 밀도를 high, medium, low 세가지 분류로 나눈다. 플랫폼에서는 실제 스 크린 밀도에 맞게 리소스들의 사이즈를 조정한다.  Density-independent pixel (dip)  밀도와 상관없이 레이아웃의 위치를 표현할 때 사용하는 가 상의 pixel 단위. Density-independent pixel 은 기본 밀도읶 160dip에서의 물리적읶 pixel과 같다.  픽셀 변홖 공식 pixels = dips * (density / 160) ANDROIDPUB.COM
  2. 지원되는 스크린 타입 Low density 120 Medium density 160 High density 240 ldpi mdpi hdpi Small • QVGA (240x320) screen 2.6"-3.0” Normal • WQVGA (240x400) • HVGA (320x480) • WVGA (480x800) screen 3.2"-3.5” 3.0"-3.5” 3.3"-4.0” • FWQVGA (240x432) • FWVGA (480x854) 3.5"-3.8” 3.5"-4.0” Large • WVGA (480x800) screen 4.8"-5.5” • FWVGA (480x854) 5.0"-5.8”  기본 스크린 (Baseline screen)  HVGA, Normal Screen, Medium density  DIP와 Pixel 1:1 매치 ANDROIDPUB.COM
  3. 서로 다른 스크린의 리소스 관리  장치 종류마다 별도의 리소스를 사용할 수 있다  스크린 사이즈 (small, normal, large)  밀도 (ldpi, mdpi, hdpi, nodip)  가로세로 비 (long, notlong)  리소스 포더 이름으로 구분 처리 res/layout/my_layout.xml Normal 스크린 사이즈 레이아웃 res/layout-small/my_layout.xml Small 스크린 사이즈 레이아웃 res/layout-large/my_layout.xml Large 스크린 사이즈 레이아웃 res/drawable-ldpi/my_icon.png Low density 를 위한 아이콘 res/drawable-mdpi/dpi/my_icon.png Medium Density를 위한 아이콘 res/drawable-hdpi/my_icon.png High Density를 위한 아이콘 res/drawable-nodpi/composite.xml Density 와 무관한 리소스 ANDROIDPUB.COM
  4. 리소스 관리 장치마다 별도의 리소스를 모두 생성해야 할까? 레이아웃과 이미지 ANDROIDPUB.COM
  5. Pixel PX 익숙함, 편함 가장 큰 실수 ANDROIDPUB.COM
  6. 3가지 해상도의 디바이스 (px) QVGA HVGA WVGA854 (240px∙320px) (240px∙320px) (480px∙854px)  모두 다른 해상도? ANDROIDPUB.COM
  7. DIP : Density Independent Pixel DIP 서로 다른 장치에서 호홖성 보장 ANDROIDPUB.COM
  8. 3가지 해상도의 디바이스 (dip) QVGA HVGA WVGA854 (320dip∙426dip) (320dip∙480dip) (320dip∙569dip)  모두 같은 넓이의 DIP ANDROIDPUB.COM
  9. TIP 1 : 레이아웃 작성 HVGA 기본 스크린에서 DIP만 사용해서 레이아웃 디자읶을 한다 px과 dip가 1:1이라 이해 쉽다 ANDROIDPUB.COM
  10. 코드에서의 DIP 변홖  그래픽 관련 메소드는 대부분 Pixel을 읶자로 받음  상수는 항상 DIP로 정의한 후 Pixel로 변홖해 사용 private static final float GESTURE_THRESHOLD_DIP = 16.0f; //상수 정의 mGestureThreshold = TypedValue.applyDimension( //Pixel 변홖 TypedValue.COMPLEX_UNIT_DIP, GESTURE_THRESHOLD_DIP, getResources().getDisplayMetrics()); private static final float GESTURE_THRESHOLD_DIP = 16.0f; //상수 정의 final float scale = getContext().getResources().getDisplayMetrics().density; mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale + 0.5f); ANDROIDPUB.COM
  11. Dimensions 리소스 이용  res/values/dimensions.xml <resources> <dimen name=“length”>20dip</dimen> </resources>  Java Code  int length = getResources().getDimensionPixelSize(R.dimen.length) ANDROIDPUB.COM
  12. 절대위치  AbsoluteLayout  절대 위치를 사용하면 높이가 다른 장치에서 원하는 데로 표시가 안될 수 있으므로 사용하지 않는다.                        ANDROIDPUB.COM
  13. 상대위치  RelativeLayout  상대 위치를 사용하면 높이가 다른 장치에서도 원하는 데로 표시하기 쉽다. ANDROIDPUB.COM
  14. 다양한 사이즈 지원 방법 1. 다양한 스크린 사이즈 처리는 안드로이드 1.6 버전 에서부터 지원됨 2. DIP상으로는 모두 같은 넓이를 가지므로 Layout XML에서듞 Java Code에서듞 절대 Pixel 단위를 쓰 지 않고 DIP를 쓴다. 3. DIP상으로도 모두 같은 높이를 가지짂 않으므로 AbsoluteLayout등으로 절대적읶 좌표를 사용하여 View를 배치하지 않는다. ANDROIDPUB.COM
  15. Bitmap 해상도  Resource  drawable : 해상도와 상관없는 xml drawable 파읷  drawable-ldpi : Low Density를 위한 이미지 파읷   drawable-mdpi : Medium Density를 위한 이미지 파읷  drawable-hdpi : High Density를 위한 이미지 파읷 ANDROIDPUB.COM
  16. Bitmap 해상도 ldpi 폴더  200px ∙ 200px  모두 다른 픽셀 크기  자동 비트맵 크기 조정 (확대) 확대를 하게 되므로 뿌옇게 되는 현상 있음 ANDROIDPUB.COM




=================================

=================================

=================================

 

 



 

 

px : 화면의 실제 픽셀 (점 하나) 단위

 

in : 실제 화면에서의 1인치 길이

 

mm : 실제 화면에서의 1mm 길이

 

pt : 1/72 인치

 

dp, dip : Density-independent Pixels, 화면 가로 해상도의 1 / 160 (one dp is one pixel on a 160 dpi screen)

 

sp, sip : Scale-independent Pixels, dp와 비슷하지만 화면 해상도 뿐만 아니라 사용자 설정 폰트 크기에도 조절된다. 

 

 

개발하다보면 폰트의 경우는 sp, 나머지는 거의 dp만 사용한다. 

그런데 sp나 dp는 xml에서만 의미가 있지 코드상에서는 오직 px만 있다. 

따라서 코드상에서도 가급적 단위를 변환을 해 줘야 한다.

 

px = (dp * getContext().getResources().getDisplayMetrics().density + 0.5f);

 

http://developer.android.com/guide/practices/screens_support.html#dips-pels

 

 

[출처] http://blog.naver.com/ds5pnz/140122660980

 

[출처] 안드로이드의 단위 px, in, mm, pt, dp, sp|작성자 진리와 생명의길

 

 

 

=================================

=================================

=================================


단말 dpi 계산법

WindowManager wm = getWindowManager(); // getWindowManager는 Activity 의 메쏘드
Display dp = wm.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
dp.getMetrics(metrics);
float dpi = metrics.density; <- density/160 으로 계산된 값 출력 (ex, 160 dpi 해상도의 경우 1.0 출력)
int densityDpi =metrics.densityDpi; <- density 출력 (160 dpi 해상도의 경우 160 출력)


 

=================================

=================================

=================================

 

 



출처: http://www.androes.com/90

안드로이드 디바이스의 경우 크게 3가지의 해상도 범주를 가지고 있는데,

LDPI(저해상도), MDPI(중해상도), HDPI(고해상도)입니다.

 

Density값은 LDPI가 120, MDPI가 160, HDPI가 240입니다. (각각 인치당 픽셀수를 이야기합니다.)

아래 표 (Table.1)를 참고하시면 결국 현재 디자인 하신 그림 파일의 기준은 HDPI를 기준으로 되어있는 것이고,

LDPI를 위해서는 당연히 120/240 = 1/2, 

MDPI를 위해서는 당연히 160/240 = 3/4로 길이당 픽셀수가 감소하는 셈입니다.

 

모든 해상도를 지원하시려면 하나의 그림 파일을 HDPI, MDPI, LDPI에 맞춰서 3개로 만들어서 개발자에게 넘기시면 됩니다.

Table 1. Screen sizes and densities of emulator skins included in the Android SDK.

  Low density (120), ldpi Medium density (160), mdpi High density (240), hdpi
Small screen QVGA (240x320)    
Normal screen WQVGA400 (240x400)
WQVGA432 (240x432)
HVGA (320x480) WVGA800 (480x800)
WVGA854 (480x854)
Large screen   WVGA800* (480x800)
WVGA854* (480x854)
 
* To emulate this configuration, specify a custom density of 160 when creating an AVD that uses a WVGA800 or WVGA854 skin.

 

 

레이아웃용 xml 파일에 기술되어야 할 dip값은 다음과 같이 계산해서 넣으시면 됩니다.

 

dip = px * (160/density)

 

density값은 HDPI, MDPI, LDPI의 값들입니다. 

결국 MDPI일때는 dip값은 px값과 같다는 것이지요.

 


모바일에서 px은 멀티 스크린을 지원할때 문제가 되기 때문에 지양한다.

그래서 여러 해상도의 화면에 맞추기 위해 모바일에서는 dip를 사용하고 있다.

안드로이드 치수
     px: pixel 10px는 정확히 10픽셀. 스크린 픽셀의 실제 크기와 밀도와 상관없다
           QVGA (320x240)에서 10px는 높이의 1/24를 차지. VGA(640x480)은 10px는 1/64를 차지.
     dip, dp: device-independent pixel. 실제 픽셀 크기와 밀도에 따른 변활르 막기 위한 단위.
          이는 dip dot independent pixel이라고도 부른다. 안드로이드는 160dpi 화면에 나타나는 것과
          똑같은 크기로 그 개체의 크기를 확대/축소 할 수 있다.
          예로 해상도가 640x480, 크기 4x3인치라면 픽셀 밀도는 160dpi므로 10dp 객체는 10px 그대로 보인다.
          그러나 640x480이고 8x6화면은 밀도가 80dpi므로 10dp 개체가 10px짜리 객체보다 두배크다.
          안드로이드가 dp를 확대하거나 축소하는 스케일은 정확친 않고 대략 맞출 뿐이다.
      sp: sclaed pixcel. dp와 비슷, 문자열과 같이 밀도 스케이이 정확해야 하는 개체의 크기를 정할 때 사용
      pts: points.텍스트 에디터 처럼 문자의 크기를 포인트로 정할 때 사용 포인트는 1포인트 1/72인치.
      in: inches
      mm: millimeters

 

240 Density 기준으로 디자인을 할때 다음과 같이 간단히 dp값을 알 수 있습니다.

dp = px / 3 * 2
dp = px * 0.66

 

1. 우리는 240 Density의 480x800 해상도를 가지고 있는 갤럭시S를 대상으로 개발/디자인 한다.
2. 모든 개발에서 사용하는 단위는 dp와 sp로만 이루어진다. (단, 이미지는 px사용)
3. 디자이너는 모든 px사이즈의 표기에 대하여 나누기 3 곱하기 2를 한 후 dp라는 단위를 사용한다.
4. 디자이너는 사용 폰트 크기에 대하여 위에 나와있는 sp 테이블 이미지를 참고하여 사용한다.
5. 디자이너는 모든 제작된 이미지들의 크기를 480x800 대상으로 제작하되 특별한 계산은 하지 않는다.
6. 개발자는 Resource Identifier중 drawable-hdpi만을 사용한다. (개인적으로 아이콘은 mdpi도 만들길 추천함)

참고URL: http://hest.tistory.com/111


관련블로그: http://gtko.springnote.com/pages/5725475

관련블로그: http://blog.naver.com/monster7575?Redirect=Log&logNo=100113840411

 


참고사이트: http://developer.android.com/guide/practices/screens_support.html



=================================

=================================

=================================

 

 



출처ㅣ http://schwein7.tistory.com/entry/Android%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-Android-Screen-View-%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%B3%B4


Screen Size

 - 스크린 크기를 대각선으로 젠 겁니다. (일반 TV 인치 재듯)

 - Large, Normal, Small 로 구분

 

 

이에 따른 폴더 이름

 

 layout>

 layout-large>

 layout-small>

 

 

 

 

 

Aspect Ratio

 - 가로와 세로의 비를 말합니다.

 - long, notlong 로 구분

 

 

 

 

 

Resolution


 - 스크린이 가진 전체 픽셀 수.

 - 안드로이드에서 직접 처리하는 경우는 없다.

 

 

 

 

 

Density


 - 물리적 넓이와 높이 안에 얼마나 많은 픽셀이 들어가는지를 말함.

 - Absolute pixel 값을 사용할 경우, 낮은 density에서는 view가 크게 나오고
  높은 density에서는 view가 작게 나오겠죠.

 - hdpi, mdpi, ldpi, nodpi 로 구분.

 - 플랫폼에서는 실제 스크린밀도에 맞게 리소스의 사이즈를 조정.
 

 

이에 따른 폴더 이름

 

 drawable-ldpi>

 drawable-mdpi>

 drawable-hdpi>

 drawable-nodpi>


 cf) DIP (Density Independent Pixel): density와 상관없이 레이아웃을 만들 때 사용.
                                    요놈을 쓰면 똑같은 모양을 유지할 수 있습니다.

 

 

  Low density (120),ldpi Medium density (160), mdpi High density (240),hdpi
Smallscreen
  • QVGA (240x320), 2.6"-3.0" diagonal
   
Normalscreen
  • WQVGA (240x400), 3.2"-3.5" diagonal
  • FWQVGA (240x432), 3.5"-3.8" diagonal
  • HVGA (320x480), 3.0"-3.5" diagonal
  • WVGA (480x800), 3.3"-4.0" diagonal
  • FWVGA (480x854), 3.5"-4.0" diagonal
Largescreen  
  • WVGA (480x800), 4.8"-5.5" diagonal
  • FWVGA (480x854), 5.0"-5.8" diagonal


/

=================================

=================================

=================================

 

 



 

 

1. 안드로이드의 다양한 해상도

-       QVGA(Quarter VGA, 240 X 320) : HTC Taboo, 엑시페리아 X10 MINI

-       HVGA(Half VGA, 320 X 480) : 안드로원, HTC G1

-       WVGA(Wide VGA, 480 X 800) : Galaxy Series, Nexus One, 엑스페리아x1

-       FWVGA(Full Wide VGA, 480 X 854) : 모토로이, 모토쿼티, 모토글램, 엑스페리아X10

-       WQVGA(Wide Quarter VGA, 240 X 400)

-       FWQVGA(Full Wide Quarter VGA, 320 X 432)

    *   VGA(Video Graphics Array, 640 X 480)

 

2. Nomal Screen 기준 density 분류

 -   Low density, ldpi (120 dpi) : WQVGA, FWQVGA

-       Medium density, mdpi (160 dpi) : HVGA

-       High density, hdpi (240 dpi) : WVGA, FWVGA

    *   QVGA(Low density, 120dpi, Small Screen)

 

3. 화면 독립적인 UI를 배치하는 가장 좋은 방법

-       레이아웃 디자인시에는 HVGA 기준 스크린 사이즈를 중심으로 dip단위만을 사용해서 디자인합니다. 320 * 480화면 기준으로 들어갈 이미지나 UI 요소들 각각의 가로 사이즈를 px로 계산한 후 코딩시에는 그 값의 단위를 dip로만 입력하면 됩니다.

-       AbsoluteLayout을 사용하지 않습니다. 즉 화면의 절대 좌표 보다는 상대 좌표를 사용한다.

-       Bitmap  HDPI 기준으로 만듭니다. 그래야 자동으로 크기가 조정 되더라도 보기에 좋습니다. , HVGA를 기준으로 계산했을 때 100 * 100이미지가 필요하다면 HDPI 기준으로 크기의 1.5배인 150*150 크기로 실 이미지를 제작하면 됩니다. 만일, 여력이 된다면 hdpi  mdpi 기준으로 각각 만드는 것도 나쁘지 않습니다. 위에서 언급했듯이 성능에 유리합니다.

-       각 장치별로 레이아웃 및 이미지를 모두 별도로 만들어서 세밀하게 조정할 수도 있지만, 이런 경우 관리가 힘듭니다. 가급적 레이아웃과 이미지를 적게 사용해서 통일된 UI를 구성하는 것이 좋습니다.

-       XML layout 파일에 wrap_content, fill_parent 를 주로 쓰고 px 단위는 dip 단위로 바꾼다.

 

4. 다양한 해상도를 지원하는 방법

1. Pre-Scaling (보통 Bitmap 이미지 처리시에 사용)

- Pre-Scaling은 로딩시점에 크기를 조절합니다. CPU에 이득이 있다고 알려져 있습니다.

Pre-Scaling은 폰의 Density를 기준으로 동일한 dpi 디렉토리에 지정된 리소스를 로딩하며 이때는 마우런 크기 변환없이 보여줍니다. , 폰이 hpi dentisy라면 res/drawable-hdpi 디렉토리 하위의 리소스를 먼저 찾아서 있다면 아무런 크기 변환없이 그대로 보여주게 됩니다. 만일, 매칭된느 리소스가 없다면 디폴트 리소스(baseline)를 로딩하고 로딩시에 적합한 density로 크기 변환을 합니다. 예를 들어 res/drawable-mdpi/ 100*100 아이콘만 존재한다고 할 때 만일 폰의 사양이 hdpi라면 안드로이드는 drawable-mdpi 하위의 아이콘을 읽을 때 자동으로 크기를 확대해서 150 * 150 bitmap을 만듭니다. 반대로 drawable-hdpi/  150*150아이콘만 존재할 때 mdpi 폰에서 읽으면 자동으로 100*100 아이콘으로 크기를 변환합니다. Drawable-hdpi drawable-mdpi에 모두 이미지가 존재한다면 별도의 스케일 변환 작업이 필요없으니 좀더 성능에 유리합니다.

 

2. Auto-scalling(pixel dimenstions and coordinates)

- Auto-scalling은 그리는 시점에 크기를 조절합니다. 메모리에 이득이 있다고 알려져 있습니다. 주로 Pixel좌표, pixel Dimesion , Application에서 사용된 Pixel 수식 등에 적용되며, 리소스가 아닌 웹이나 SD카드에서 Bitmap데이터를 가져왔을 때도 적용됩니다. 쉽게 예기하면 App에서 (10, 10)에서 (100, 100) 좌표로 4각형을 기리도록 구현햇다면 High-Density(240dpi) 화면을 가진 Device에서는 그리는 시점에 자동으로 스케일을 변환해서 (15, 15) (150, 150)좌표에 사각형을 그리게 된다.


 

용어정리

 

1. 스크린 사이즈(Screen Size)

-       스크린 사이즈는 스크린의 대각선 크기를 재어지는 물리적인 크기를 나타낸다. 안드로이드는 스크린 사이즈를 크게 3가지로 분류하는 데 large, normal, small로 나눈다.

 

   2. 가로세로 비(Aspect ratio)

-   가로세로 비는 스크린의 물리적인 넓이와 넓이의 비율로 결정된다. 안드로이드는 가로세로 비를 longnotlong으로 나눈다.

 

   3. 해상도 (Resolution)

-   스크린이 가지고 있는 전체 픽셀의 수. 해상도는 종종 넓이 x 높이로 표현되지만 해상도가 특정 가로-세로 비를 의미하지는 않는다. 안드로이드에서는 해상도를 직접 처리하지 않는다.

 

    4. 밀도 (Density)

    -   스크린 해상도를 기반으로 물리적인 넓이와 높이 안에 얼마나 많은 픽셀이 들어있는가를 나타낸다. Lower density의 스크린에서는 같은 넓이와 높이 안에 더 적은 수의 픽셀이 있고, higher density의 스크린에서는 같은 넓이와 높이 안에 더 많은 수의 픽셀이 있다. 안드로이드는 밀도를 high, medium, low 세가지 분류로 나눈다. 플랫폼에서는 실제 스크린 밀도에 맞게 리소스 들의 사이즈를 조정한다.

 

*  안드로이드 기본 스크린 (Baseline Screen)

-       HVGA, Normal Screen, Medium density

 

출처:http://pheadra.tistory.com/181?srchid=BR1http%3A%2F%2Fpheadra.tistory.com%2F181

 

 

=================================

=================================

=================================

 


출처: http://ma.androidside.com/bbs/board.php?bo_table=B49&wr_id=12049

 

저도 그쪽 부분을 여기저기 찾아서 해봤는데 헤맸어요... 
저 같은 경우는 그냥 스케일 비율로 불러와서 처리했습니다만.. 

final float scale = getContext().getResources().getDisplayMetrics().density;

// 스케일 곱해서 처리
canvas.drawLine(StartX * scale, StartY * scale, StopX * scale, StopY * scale, pnt);

// 터치 이벤트
public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // 선택 위치
            int selX;
            int selY;
            selX = (int) event.getX();
            selY = (int) event.getY();

            if (selY >= (int)(20 * scale) && selY <= (int)(60 * scale)) {
                // ... 생략 ...

정확히 할려면 가로 세로 해상도 따로 요런식으로 구해서 쓰시면 될꺼 같습니다..

final float hPixel = getContext().getResources().getDisplayMetrics().heightPixels;
final float wPixel = getContext().getResources().getDisplayMetrics().widthPixels;

삽질(?)하면서 얻은거라 좋은 방법인지는 모르겠네요 ^^;;;;

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

어...dip 단위랑 다르면 터치 좌표나 다르게 나오는건가요? 
폰 해상도마다 조금씩 달라서 줄려고 했는데 허허..이거 대략 난감이네요.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

참고 하시길.. 

DisplayMetrics metrics = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getMetrics(metrics);
Log.d("test", "density=" + metrics.density);
Log.d("test", "densityDpi=" + metrics.densityDpi);
Log.d("test", "scaledDensity=" + metrics.scaledDensity);
Log.d("test", "widthPixels=" + metrics.widthPixels);
Log.d("test", "heightPixels=" + metrics.heightPixels);
Log.d("test", "xDpi=" + metrics.xdpi);
Log.d("test", "yDpi=" + metrics.ydpi);

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

이건 어떤지요.. 

WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Log.d("display", "w:" + display.getWidth());
Log.d("display", "h:" + display.getHeight());

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

감사합니다. 스크랩해 가요~*^.^*

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

=================================

=================================

=================================

 

 

 

출처: http://www.androidpub.com/2573998

 

안녕하세요. 

안드로이드에서 개발을 할 때 디바이스 해상도 대응이 참 문제죠?

이 부분에 대해서 해결을 한 라이브러리가 있어서 이렇게 공개를 합니다.

에브리싱 이라는 상용 서비스에서도 이용된 기술입니다.

에브리싱은 GooglePlay Awards에서도 선정되어 어느정도 검증된 기술이라고 생각해주셔도 될 것 같습니다.

https://play.google.com/store/apps/details?id=com.sm1.EverySing

 

 

오픈소스프로젝트의 링크는 아래와 같습니다.

https://github.com/ssomai/ScalableLayout

 

클래스파일의 링크는 아래와 같습니다. 이 java 파일 단 하나만 project에 포함시키시면 됩니다.

https://github.com/ssomai/ScalableLayout/blob/master/ScalableLayout/src/com/jnm/android/widget/ScalableLayout.java

 

 

자바로 뷰를 배치하는 예시 코드

https://github.com/ssomai/ScalableLayout/blob/master/ScalableLayout_TestAndroid/src/com/jnm/android/widget/scalablelayout_testandroid/MainActivity.java

 

// ScalableLayout의 사이즈를 400 x 200 으로 설정합니다.
// 상대적인 단위로 pixel 이나 dp 단위가 아닙니다.
ScalableLayout sl = new ScalableLayout(this, 400, 200);
sl.setBackgroundColor(Color.LTGRAY);

// ScalableLayout에 TextView를 넣어보겠습니다.
TextView tv = new TextView(this);
tv.setText("test");
tv.setBackgroundColor(Color.YELLOW);

// 왼쪽 x 좌표는 20, y좌표는 40, width는 100, height는 30으로 ScalableLayout에 TextView를 넣습니다.
// 단 한줄의 코딩으로 view를 넣은 후 이후에는 자동으로 리사이즈 됩니다.
sl.addView(tv, 20 f, 40 f, 100 f, 30 f);

// TextView 안의 text의 사이즈를 20으로 설정합니다. text의 사이즈도 자동으로 조절됩니다.
sl.setScale_TextSize(tv, 20 f);

// ScalableLayout에 ImageView를 넣어보겠습니다.
ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.ic_launcher);

// 왼쪽 x 좌표는 200, y좌표는 30, width는 50, height도 50으로 ScalableLayout에 ImageView를 넣습니다.
// 단 한줄의 코딩으로 view를 넣은 후 이후에는 자동으로 리사이즈 됩니다.
sl.addView(iv, 200 f, 30 f, 50 f, 50 f);

 


XML로 뷰를 배치하는 예시 코드

https://github.com/ssomai/ScalableLayout/blob/master/ScalableLayout_TestAndroid/res/layout/activity_main.xml

 

<com.jnm.android.widget.ScalableLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/darker_gray"
    android:layout_above="@+id/main_textview"
    sl:scale_base_width="400"
    sl:scale_base_height="200">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        sl:scale_left="20"
        sl:scale_top="40"
        sl:scale_width="100"
        sl:scale_height="30"
        sl:scale_textsize="20"
        android:text="@string/hello_world"
        android:textColor="@android:color/white"
        android:background="@android:color/black"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        sl:scale_left="200"
        sl:scale_top="30"
        sl:scale_width="50"
        sl:scale_height="50"
        android:src="@drawable/ic_launcher"/>
</com.jnm.android.widget.ScalableLayout>

 

추가로 아래에 한글 설명서를 덧붙였습니다. 

사용해보시고 궁금한 점이 있으시면 댓글로 질문 주시면 수시로 답변 드리겠습니다.

별도로 또 궁금한 점이 있으시면 ssomai@gmail.com 으로 질문 주셔도 됩니다.

 

감사합니다~~~!!!

 

========================================================================================================================

 

ScalableLayout for Android.

Class: com.jnm.android.widget.ScalableLayout

단 한번의 코딩으로 태블릿을 포함한 모든 화면에서 정확한 UI를 표현하고 싶다면!

ScalableLayout은 화면의 크기가 매우 다양한 안드로이드 폰과 태블릿 환경에서
일관성 있는 UI를 표현하기 위한 방법 중의 하나입니다.

ScalableLayout은 android에서 widget을 감싸는 용도로 쓰이는
FrameLayout 이나 LinearLayout 대신 이용될 수 있는 Layout 입니다.

UI를 구성하는 TextView나 ImageView 같은 view 들은
ScalableLayout 안에서 상대적인 (x,y) 좌표와 (width, height) 값을 부여받은 뒤,
ScalableLayout 의 크기가 변함에 따라 비율에 맞춰 위치와 크기가 자동으로 변화됩니다.
TextView나 EditText같이 텍스트가 들어가는 view들은 (text size) 값을 부여하면
텍스트 크기가 ScalableLayout의 크기에 맞춰서 변화됩니다.


ScalableLayout은 단 하나의 java file을 import하는 것만으로 모든 기능을 제공합니다.
Java 또는 XML 의 Android 에서 UI를 구성하는 두가지 방법 모두에서 ScalableLayout을 이용할 수 있습니다.

ScalableLayout은 2013년에 Google Play에서 빛난 올해의 앱 모음에 선정된
S.M.ENTERTAINMENT의 everysing 앱에서도 이용되어 그 우수성을 증명한 바 있습니다.

다양한 비율의 화면에서 ScalableLayout이 적용된 예.

왼쪽부터 삼성 갤럭시 S4 (1920 x 1080. 16:9), LG 옵티머스 뷰2 (1024 x 768. 4:3), 갤럭시 노트 10.1 (1280 x 800. 8:5)


모든 사이즈의 화면에서 각각의 UI가 정확하게 표현되어 있습니다.

ListView에서 각각의 UI가 정확하게 표현되어 있습니다.

다이얼로그에서도 각각의 UI가 정확하게 표현되어 있습니다. 비율대로 표현되기 때문에 옵티머스뷰2에서는 좌우의 여백이 큽니다.

 

 

목록

엮인글 주소 : http://www.androidpub.com/index.php?document_srl=2573998&act=trackback&key=ac8

 

2013.12.18 10:44:22

헐헐

보시는 것처럼 단 한번의 코딩으로 소형 안드로이드 폰부터 10인치의 안드로이드 태블릿까지 깔끔하게 UI를 표현해 낼 수 있습니다.

 

꽤 좋은? 제가 보기에는 정말 좋은 Android 에서의 UI 구성 Layout 입니다. 

 

2013.12.19 11:16:56

마플

좋군요.

이미 짜여진 레이아웃을 동적 변환해주는 방향이었으면 더 좋았겠는데 하는 생각이 들지만...

어려우려나요? 

 

ps. 라이센스는 어디 기재되어 있나요?

 

2013.12.20 09:50:57

김영만

 

감사합니다 ^^

 

라이센스는 BSD license이니 자유롭게 쓰시면 됩니다.

라이센스 문서는 여기에 기재되어있습니다.

https://github.com/ssomai/ScalableLayout/blob/master/LICENSE.md

 

감사합니다 ^^

 

 

2013.12.27 14:09:24

김영만

관심가져주셔서 감사합니다~.

ScalableLayout 이용과 관련하여 궁금한 점이 있으시면 
언제든지 리플이나 ssomai@gmail.com로 연락 주세요.

감사합니다.

 

2013.12.27 16:09:22

Trait

와우 좋네요~

안드로이드 파편화 문제가 여러가지 방법으로 조금씩 해결 되가는거 같아서 다행이예요 ㅎㅎ

 

2014.01.06 14:05:44

살구

좋은 소스 감사합니다~

 

2014.01.31 22:37:05

ph20531

정말 좋네요 ㅎ
근데 한 레이아웃에 리스트뷰랑 에디트텍스트 두고 실행하고 에디트텍스트를 누르고 키보드가 올라올때 리스트뷰가 압축되고 비율로 화면배치하다보니까 리스트뷰 따라서 다른 뷰들도 비율적으로 작아지네요 ㅠㅜ

2014.02.25 10:04:54

김영만

네 맞습니다~

키보드가 올라가면 그런 문제가 있으십니다.

 

ScalableLayout의 android:layout_height쪽에 wrap_content를 사용하시거나

Activity의 android:windowSoftInputMode쪽에 adjustPan을 사용하시면 되지 않을까 생각합니다~.

 

2014.02.21 00:08:53

qwlwwmq

안녕하세요 질문이 있어서 질문드립니다. 

xml파일을 보니 다음과 같은 소스가 있는데요 이건 어떻게 수정이 되어야 하는건가요? 

xmlns:sl="http://schemas.android.com/apk/res/com.jnm.android.widget.scalablelayout_testandroid"

 

2014.02.25 10:08:12

김영만

네 답변이 늦어서 죄송합니다~

해당 코드는 com.jnm.android.widget.scalablelayout_testandroid를 application project로 바꾸시면 됩니다~.

github에도 같이 답변을 달았습니다~

 

github이나 메일로 문의주시면 저에게 알림이 와서 

더 빠른 답변이 가능할것 같습니다 ㅎㅎ

 

2014.05.14 23:15:41

잔인한귀요미

영만님 안녕하세요? 이승환입니다!

Scalablelayout 너무너무 잘 쓰고 있습니다..ㅠㅠ

감사합니다!!

 

2014.08.13 12:29:06

김영만

오 승환님~

잘 지내시고 있나요~ ㅎㅎ

잘 써주시니 감사합니다~~ ㅎㅎ

 

2014.05.29 10:27:50

안드로이드초보22

저기 저는왜 pAttrs, R.styleable.ScalableLayout 이부분에서 sytleable <- 이부분이 오류가납니다; 클래스파일 그대로 가져가서 프로젝트 src 에 복사 햇는데.

 

2014.07.25 14:58:21

안녕탁이

그거

ScalableLayout / ScalableLayout / res / values / attrs.xml

이것도 넣어주셔야 돼요;

https://github.com/ssomai/ScalableLayout/blob/master/ScalableLayout/res/values/attrs.xml

그리고 R은 Android의 R import가 아니고

해당 프로젝트의 R을 import 시켜야합니다

 

2014.08.13 12:29:55

김영만

와, 제 대신 답변 달아주셔서 감사합니다~~ ㅎㅎ

요렇게 해주시면 됩니다 >_<

 

2014.10.28 18:00:30

llpmpll

저도 안드로이드초보22님과 같은 부분에서 에러가 발생합니다.

attrs.xml도 넣었고 xml에서 패키지명도 수정했습니다만... 

여전히 sytleable에서 에러가 발생중입니다.

 

어느 부분을 수정해야 될지 모르겠습니다.

 

 

=================================

=================================

=================================

 

 


*기타 사이트

- http://theeye.pe.kr/entry/few-tips-for-android-programmer-and-ui-designer

 

=================================

=================================

=================================

 

 

반응형