Category Archives: Programming

Android ListView : 아이템 갯수가 적을 때 보이지 않는 현상

리스트뷰 사용시 아이템 갯수가 스크롤이 될 만큼 많지 않을 때

데이터는 있는데 리스트에 표시 되지 않는 경우가 있다.

이건 리스트뷰의 height가 제대로 적용이 안되는건데

아마 99% 이상의 확률로

리스트뷰를 FrameLayout 으로 감싸놓았을 것이다.

FrameLayout 을 RelativeLayout 으로 바꿔서 사용하면

해결됨

FrameLayout … 멍닐라ㅣㅜ나미퍼ㅣㄴㅁㅇ ㅠ_ㅠ

 

android – Pull To Refresh ListView

아이폰처럼 안드로이드도 리스트뷰를

아래로 당기면 재조회 할수가 있다.

 

아래 주소가서 소스 받아서 보면 된다. -_-..

 

 

https://github.com/johannilsson/android-pulltorefresh

 

johannilsson 이놈 천재인듯 -_-…

 

내가 바보인 건지도(?);;

 

 

궁금한건 댓글주세용 ㅋ

 

 

PS. 조회가 완료되면 listview.onRefreshComplete(); 를 호출해 주어야 다음 재조회가 가능해진다.

 

 

느린 SimpleDateFormat 대신 FastDateFormat 을 사용하자!

안드로이드에서 날짜를 뿌리는 리스트뷰를 만들어야 했는데

리스트 뷰 스크롤이 엄청 느렸다. -_-

왜 그런가 살펴보니 SimpleDateFormat 이 문제였다.

엄청 느림.. -_-..;;;

 

해결책은

아파치에서 제공해주는 FastDateFormat을 사용하는 것!

 

1. 우선 commons-lang-2.4.jar 을 다운 받아 프로젝트에 임포트 시키고 시작.

 

사용법은 아래 함수 참고~

 

 

 

/**

* 문자열을 Date 객체로 변환

@param toStr

@return

*/

public static Date parseDate(String toStr) {

Date date = null;

try {

String[] parsePattern = {“yyyy-MM-dd HH:mm:ss Z”};

date = org.apache.commons.lang.time.DateUtils.parseDate(toStr, parsePattern);

catch (ParseException e) {

e.printStackTrace();

}

return date;

}

 

 

public static String formatDateTimeToString(String toDate) {

if(!toDate.equals(“”)){

Date date = parseDate(toDate);

 

FastDateFormat format = FastDateFormat.getInstance(“yyyy-MM-dd HH:mm”, TimeZone.getDefault(), Locale.getDefault());

return format.format(date);

}else{

return “”;

}

}

 

 

속도 엄청 빨라진다~~~ ㅎㅎ

 

궁금한 점은 댓글로!

 

 

 

 

ps. Library 원본은

 

http://grepcode.com/project/repo1.maven.org/maven2/commons-lang/commons-lang/

 

여기

 

slidingdrawer left to right

slidingdrawer 는 우에서 좌, 하에서 상으로 밖에 움직일 수 없다.

근데 좌에서 우, 상에서 하로 구현하고 싶다.

그래서 구글링을 해서 소스를 얻을 수 있었다.

엄밀히 말해서 slidingdrawer 로 구현한건 아닌데

비슷한 기능인듯…

android-misc-widgets

라는 소스고 svn 주소가 이상해서 여차여차 해서 구했다.

필요하심 첨부파일 다운 받아서 연구해보세용 ㅎㅎ;

 

AndroidMiscWidgets.zip

 

 

[Android] MediaScan 의 finish 캐치

sendBroadcast  를 실행하기 전에 미디어스캐너의 종료를 잡을 리시버를 등록한다.

IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
intentFilter.addDataScheme(“file”);
registerReceiver(mReceiver, intentFilter);

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { // 미디어스캐너의 시작 감지
System.out.println(“Media Scanner started scanning ” + intent.getData().getPath());
}
else if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { // 미디어스캐너의 종료 감지
System.out.println(“Media Scanner finished scanning ” + intent.getData().getPath());
}
}
};

 

안드로이드 해상도별 스크린 레이아웃

—QVGA(240×320), 120dpi : HTC Tatoo
—HVGA(320×480), 160dpi : 안드로원, HTC G1
—WVGA(480×800), 240dpi : 넥서스원, 갤럭시A
—FWVGA(480×854), 240dpi : 모토로이
1. Low desity 120 – ldpi
    QVGA(240×320)  : 2.6~3.0
    WQVGA(240×400) : 3.2~3.5
    FWQVGA(240X432) : 3.5~3.8
2. Medium density 160 – mdpi
   HVGA(320X480) : 3.0~3.5
   WVGA(480×800) : 4.8~5.5
   FWVGA(480X854) : 5.0~5.8
3. High density 240 – hdpi
   WVGA(480×800) : 3.3~4.0
   FWVGA(480X854) : 3.5~4.0
4. x High density 320 – xhdpi
    (720*1280)
갤럭시탭 10.1
drawable-xlarge-mdpi
layout-xlarge 또는 layout-1280×800
갤럭시탭 7.0
drawable-large-hdpi
layout-1024×600
일반폰 (480×800)
drawable-hdpi
layout
HD폰(1280×720)
drawable-xhdpi
layout-1280×720
갤럭시넥서스: layout-sw360dp
갤럭시노트: layout-xhdpi-1280×800 (or layout-normal-xhdpi)
갤럭시탭10.1: layout-xlarge-mdpi(3.2이상 버전에서는 layout-sw800dp로도 가능)
HD(1280×720)폰: layout-xhdpi-1280×720 (layout-normal-xhdpi)
HTC Evo4g: layout-hdpi-960×540
res/layout/ 폴더를 더더욱 구분하여 스마트폰의 해상도별 xml을 나눌뿐만 아니라
태블릿도 구분할수 있게되었어요(원래 그랬던건지..그냥 새로 만들어준건지는 나도몰라아아아)
res/layout/main_activity.xml          -> 스마트폰
res/layout-sw600dp/main_activity   -> 7인치 태블릿
res/layout-sw720dp/main_activity   -> 10인치 태블릿
public class MyActivity extends Activity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate();
Configuration config = getResources().getConfiguration();
if (config.smallestScreenWidthDp >= 600) {
setContentView(R.layout.main_activity_tablet);
} else {
setContentView(R.layout.main_activity);
}
}
}
—리소스포더이름으로구분처리
서로다른스크린의리소스관리
 – 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
MediumDensity를위한아이콘
 – res/drawable-hdpi/my_icon.png
High Density를위한아이콘
 – res/drawable-nodpi/composite.xml
Density 와무관한리소스
—밀도(Density)
—스크린해상도를기반으로물리적인넓이와높이안에얼마나많은픽셀이들어있는가를나타낸다. Lower density의스크린에서는같은넓이와높이안에더적은수의픽셀이있고, higher density의스크린에서는같은넓이와높이안에더많은수의픽셀이있다. 안드로이드는밀도를high, medium, low 세가지분류로나눈다. 플랫폼에서는실제스크린밀도에맞게리소스들의사이즈를조정한다.
—Density-independent pixel (dip)
—밀도와상관없이레이아웃의위치를표현할때사용하는가상의pixel 단위. Density-independent pixel 은기본밀도인160dip에서의물리적읶pixel과같다.
—픽셀변환공식pixels = dips * (density / 160)
아…저 토나오는 광경…같은게 하나도 없는 물건들…
갤럭시 노트
해상도  :  1280 * 800
Density  :  xhdpi
크기  :  5.3인치(large screen)
OS  :  Android 2.3 갤럭시 S2
해상도  :  800 * 480
Density  :  hdpi
크기  :  4.3인치(normal screen)
OS  :  Android 2.3  갤럭시 탭 10.1
해상도  :  1280 * 800
Density  :  mdpi
크기  :  10.1인치(xlarge screen)
OS  :  Android 3.0
안드로이드 마켓에 릴리즈시 하나의 어플리케이션에 두개의 APK파일을 등록할 수 있는 MultipleScreens 기능이 있다.
AndroidManifest.xml 의 스크린사이즈가 다르거나 SDK Version이 다른 두개의 APK파일을 업로드
하여 Publish하면 되는거..
하지만 해상도의 구분이 애매하였다.
열심히 구글링을 해보면…아래값들을 컨트롤하면 된다.
smallScreens = true (normalScreens 보다 작은 사이즈 지원)
normalScreens = true (normalScreens 사이즈 지원)
largeScreens = true (normalScreens 보다 큰 사이즈 지원)
xlargeScreens = true (largeScreens 보다 큰 사이즈 지원)
requiresSmallestWidthDp = 600 (Android 3.2 API Level 13이후부터 지원하는 attribute.
 600에 largeScreens = true, xlargeScreens = true를 설정하면 타블렛만
 지원되는 어플이 된다.)
<supports-screens android:resizeable=[“true”| “false”]
                  android:smallScreens = [“true” | “false”]
                  android:normalScreens = [“true” | “false”]
                  android:largeScreens = [“true” | “false”]
                  android:xlargeScreens = [“true” | “false”]
                  android:anyDensity=[“true” | “false”]
                  android:requiresSmallestWidthDp=”integer”
                  android:compatibleWidthLimitDp=”integer”
                  android:largestWidthLimitDp=”integer”/>
즉…..2.3에선 requiresSmallestWidthDp를 사용할 수 없고, 갤노트와 갤S2는 아래와 같이 구분하여 적용
시키면 마켓 필터링이 가능하다.
*. 갤럭시 S2
<supports-screens
     android:smallScreens=”false”
     android:normalScreens=”true”
     android:largeScreens=”false”
     android:xlargeScreens=”false”
     android:anyDensity=”true”
/>
 *. 갤럭시 노트
<supports-screens
     android:smallScreens=”false”
     android:normalScreens=”false”
     android:largeScreens=”true”
     android:xlargeScreens=”false”
     android:anyDensity=”true”
/>
?추가로 엄청 중요한 사항이 생겼다. 위와 같이 했을 경우 마켓 릴리즈시 버전코드가 갤럭시 S2가
더 낮아야 한다. 즉!! 갤럭시 S2의 버전코드가 100이라면 갤럭시 노트의 버전코드는 101이 되어야
정상적인 릴리즈가 가능하다. 만약 갤럭시 노트의 버전 코드가 더 낮다면 빨간색 에러줄을
마주치게 된다. 아…이것때문에 엄청 암울했는데…ㅠㅠ
혹 여기서 10.1인치를 필터링 시키려면 안드로이드마켓 등록시 지원등록단말에서 수동
삭제하면…ㅋㅋㅋㅋ된다.
내가 삽질한건??? 내가 원한건 다른 사이즈들은 다빼고 딱 normalScreens만 지원하고 싶었을 뿐인데…
이게 normalScreens = true로 하고, 다른 스크린을 false로 설정해도 normalScreens~xlargeScreens까지
지원된다는거다…
그래서 찾아보다가 아래와 compatible-screens를 찾게되었다. 역기서 screenSize=”normal”로 설정하면
마켓상에서 딱!!!normalScreens만 지원된다…
허나…compatible-screens를 적용시키면 지원단말에서 국산단말은 제외되고,
해외향 단말만 지원된다.
젠장…된장…진장…아래처럼 모든 Density에 모든 screenSize를 설정해도 국내향단말은
지원단말에서 제외되어있다…ㅠㅠㅠㅠ
이걸 하나씩 확인해보다…왜 갤노트는 제외되지…왜 갤S2는 제외되지…
그러다 모든걸 적용시켜도 안된다는걸 알고 포기함.
    <compatible-screens>
        <screen android:screenDensity=”xhdpi” android:screenSize=”small”/>
        <screen android:screenDensity=”ldpi” android:screenSize=”small”/>
        <screen android:screenDensity=”mdpi” android:screenSize=”small”/>
        <screen android:screenDensity=”hdpi” android:screenSize=”small”/>
        <screen android:screenDensity=”xhdpi” android:screenSize=”normal”/>
        <screen android:screenDensity=”ldpi” android:screenSize=”normal”/>
        <screen android:screenDensity=”mdpi” android:screenSize=”normal”/>
        <screen android:screenDensity=”hdpi” android:screenSize=”normal”/>
        <screen android:screenDensity=”xhdpi” android:screenSize=”xlarge”/>
        <screen android:screenDensity=”ldpi” android:screenSize=”xlarge”/>
        <screen android:screenDensity=”mdpi” android:screenSize=”xlarge”/>
        <screen android:screenDensity=”hdpi” android:screenSize=”xlarge”/>
        <screen android:screenDensity=”xhdpi” android:screenSize=”large”/>
        <screen android:screenDensity=”ldpi” android:screenSize=”large”/>
        <screen android:screenDensity=”mdpi” android:screenSize=”large”/>
        <screen android:screenDensity=”hdpi” android:screenSize=”large”/>
     </compatible-screens>
1. 마지막으로 dpi구하는 공식
  context.getResources().getDisplayMetrics().density;
2. dpi를 픽셀로 변환하는 공식
public static int convertDipToPx(Context context, int dip){
  final float scale = context.getResources().getDisplayMetrics().density;
  return (int) (dip * scale + 0.5f);
}