Android2014. 4. 6. 13:18

ListView 2개를 ScrollView로 감싸서 ListView2개가 ScrollView 높이를 초과하게 되면 스크롤 되어 보여지게 UI를 구성했습니다.

문제는 ListView 2개의 heigh를 wrap_content나 match_parent를 주고 ScrollView로 감싸게 되면 ScrollView에서는 ListView의 height를 제대로 인식하지 못해서 ScorllView안의 ListView들이 제대로된 height 만큼 표시되지 않고 잘려서 표시되게 됩니다.

그렇다고 ListView에 heigh를 고정 크기로 지정해주게 되면 정작 ListView의 아이템 개수에 맞게 ListViewt를 표시 할수 없는 문제가 생깁니다.

그래서 ListView를 제대로 표시할 수 있는 방법을 찾아보니 ListView의 초기화 및 Item(data)을 갱신한후 ListView의 height를 계산하여 ListView에 LayoutParams을 설정하는 방법이 있더군요 이방법을 적용해보니 ListView가 제대로 표시되고 스크롤도 가능하게 됩니다.

소스코드를 공유 하자면

protected void onCreate(Bundle savedInstanceState) {
        ListView listview1 = (ListView) view.findViewById(R.id.list1);
        ArrayAdapter<Data> adapter = new ArrayAdapter<Data>(this, R.layout.simple_list_item, listData1);
        listview1.setAdapter(adapter);

        ListView listview2 = (ListView) view.findViewById(R.id.list2);
        adapter = new ArrayAdapter<Data>(this, R.layout.simple_list_item, listData2);
        listview2.setAdapter(adapter);

        setListViewHeightBasedOnChildren(listview1);
        setListViewHeightBasedOnChildren(listview2);
}

public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter(); 
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
        listView.requestLayout();
}

리스트 뷰가 갱신될때 setListViewHeightBasedOnChildren() 호출을 하게 되면 ListView를 ScrollView로 감싸게 UI를 구성하더라도 ListView 정상적으로 표시되고 스크롤이 되게 됩니다.

 

Posted by 위푸
Android2011. 6. 7. 09:35
Android에서 View의 크기를 알아오고 싶을때 일반적으로

 view.getWidth();
 view.getHeight();
위의 api를 써서 원하는 view의 크기를 얻어 옵니다.
위의 방법은 View가 onDraw를 통하여 화면에 그려 졌을 경우에 크기를 얻을 수 있습니다. 만약 그전에 위의 api를 호출하게 된다면 0값을 얻어오게 됩니다.

만약 onDraw전에 View에 크기를 알고 싶은 경우에는
view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); 
view.getMeasuredWidth();
 view.getMeasuredHeight();
위의 api를 사용하면 됩니다.
여기서 중요한 것은 view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED) 메소드 인데 이 메소드를 통하여 view의 부모에게 크기를 위임하여 알아오게 해줍니다. 위 메소드의 파라미터로 넘겨지는 MeasureSpec은

MeasureSpec.AT_MOST : wrap_content 에 매핑되며 뷰 내부의 크기에 따라 크기가 달라진다.
MeasureSpec.EXACTLY : fill_parent, match_parent 로 외부에서 미리 크기가 지정되었다.
MeasureSpec.UNSPECIFIED : Mode 가 설정되지 않았을 경우. 소스상에서 직접 넣었을 때 주로 불립니다.

위와 같은 설정을 지원해줌으로 원하는 설정값을 넘겨주시면 됩니다.

도움이 되셨으면 좋겠네요~ ^^
Posted by 위푸
Android2010. 1. 3. 15:25
Android API에서는 데이터 베이스의 데이터 값이 변경되었을경우 Notifications을 제공해주는 ContentObserver라는 API를 제공하여 줍니다.  

- 사용법 예제 소스입니다.

public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");

// 해당 데이터베이스의 데이터값이 변경시에 onChange() method가 호출됩니다.
private ContentObserver bookmarksObserver = new ContentObserver(new Handler()) {
     @Override
     public void onChange(boolean selfChange) {
          super.onChange(selfChange);
          Log.d("Boookmarks", "onChanged : " + selfChange);
     }
};

// ContentObserver에 해당 데이터 베이스의 URI를 등록합니다.
private BookmarksManager(Context context) { 
     this.context = context;
     this.contentResolver = context.getContentResolver();
     contentResolver.registerContentObserver(BOOKMARKS_URI, true, bookmarksObserver );
}

// 해당 Manager Class가 소멸될경우 꼭 ContentObserver에서 해제 시켜주어야 합니다
public static void destroy() {
     if (instance != null && instance.contentResolver != null && instance.bookmarksObserver != null) {
          instance.contentResolver.unregisterContentObserver(instance.bookmarksObserver);
     }
     instance = null;
}
Posted by 위푸