2009-11-02 20 views
54

Tôi có một ListView khá phức tạp, với chiều cao mục danh sách biến. Trong một số điều kiện nhất định, tôi cần hiển thị một chế độ xem bổ sung trong một mục danh sách, được ẩn theo mặc định (View.GONE). Bằng cách kích hoạt nó (View.VISIBLE), mục danh sách phát triển theo chiều cao (hoặc ít nhất nó được cho là).Tại sao các mục ListView không phát triển để bao bọc nội dung của chúng?

Vấn đề: Mặc dù tôi khai báo bố cục gốc của mặt hàng thành wrap_content, và mỗi thành phần trong mục để fill_parent, chế độ xem tôi ẩn/hiển thị được cho là thay đổi chiều cao của mục chỉ đơn giản là cắt ở dưới cùng của bố mẹ của nó (bố cục mặt hàng) phát triển theo chiều cao để hiển thị đầy đủ nó.

Có bất kỳ gotchas nào liên quan đến ListView và bố cục mục và chiều cao mục mà tôi có thể đã bỏ qua không?

Một số chi tiết quan sát:

Đối với mục đích thử nghiệm bây giờ tôi đã giảm bố trí danh mục chỉ chứa LinearLayout gốc và một ImageView. Khi tôi đặt chiều cao LinearLayout thành ví dụ: 200dip và ImageView để fill_parent, tôi đã mong đợi ImageView sẽ phát triển cho đến khi nó đạt đến giới hạn 200dip do cha mẹ của nó đặt.

Tuy nhiên, hình ảnh sẽ chỉ cao bằng tài nguyên bitmap của nó (như tôi đã đặt nó thành wrap_content) và toàn bộ mục danh sách sẽ có cùng chiều cao (ví dụ như tôi đã đặt nó thành wrap_content , quá).

Nếu tuy nhiên tôi đặt chiều cao hình ảnh thành ví dụ: 200dip, khi đó mục danh sách sẽ tăng theo chiều cao và bố cục mặt hàng cũng vậy.

Nói cách khác, layout_height của bố cục mục danh sách bị bỏ qua hoàn toàn và do đó, bất kỳ giá trị độ cao nào trên ImageView khác với giá trị pixel được mã hóa cứng.

+2

HI .. Matthias Vui lòng cung cấp cho tôi ví dụ làm việc. Tôi cũng phải đối mặt với cùng một vấn đề, nhưng không rõ làm thế nào u giải quyết. vấn đề. –

Trả lời

54

tôi quản lý để khắc phục điều này, nhưng tôi không hiểu tại sao .

Như tôi đã đề cập, tôi đã đặt layout_height của bố cục mục danh sách thành wrap_content (vì fill_parent là vô nghĩa ở đây, cho rằng một ListView cao vô hạn).

Tuy nhiên, tôi đã đặt layout_height của tất cả các chế độ xem bên trong bố cục đó thành fill_parent. Sự cố đã biến mất khi đặt chúng thành wrap_content thay thế.

Điều này đặt ra hai câu hỏi khác:

1) ngữ nghĩa của một cái nhìn hỏi để fill_parent là gì, khi phụ huynh wraps_content? Yêu cầu kích thước nào được ưu tiên?

2) Làm thế nào tôi có thể làm cho một cái nhìn điền vào một mục danh sách nếu fill_parent dường như không hoạt động?

Cảm ơn các bạn đã nhập liệu.

+0

Thx cho rằng Matthias =) Tôi đã có vấn đề tương tự exakt. Tôi cũng đã đặt layout_height thành "fill_parent". Tôi nghĩ cái đó là hiển nhiên. Nhưng đúng là bạn, khi thiết lập để "wrap_content" nó giải quyết vấn đề. Lạ ... – Ted

+1

Cảm ơn bạn! Điều này đã giết chết tôi. –

+0

ok, vì lý do nào đó, tôi đã có một vấn đề tương tự, nhưng khi tôi chỉ có một mục trong danh sách, thì toàn bộ danh sách xem sẽ quá nhỏ so với màn hình đầu tiên. Vì vậy, khi tôi tăng kích thước vật phẩm, tầm nhìn sẽ không phát triển. Tôi phải đặt chế độ xem thành "fill_parent" để hoạt động. Bây giờ, tôi cần phải xem điều gì xảy ra khi tôi có vô số vật phẩm trong đó. – Mortimer

21

Bạn làm cách nào để tăng thêm hàng?

Nếu bạn không sử dụng nó ngay bây giờ, hãy thử sử dụng LayoutInflater#inflate(layoutId, parent, false) (nơi parentAdapterView cung cấp cho getView() hoặc newView()):

v = getLayoutInflater().inflate(R.layout.list_item, parent, false); 
+0

Xin chào Mark, ngữ nghĩa của việc cung cấp chế độ xem gốc để tăng(), nhưng đặt attachToRoot thành false là gì? Nếu chế độ xem nội tuyến không được đính kèm với rootView, thì điều gì khác được thực hiện với chế độ xem đó? – Matthias

+0

Tôi xin lỗi, tôi quên đề cập đến: Tôi vượt qua null cho rootView và false cho attachToRoot. Sau khi tất cả, view được trả về bởi adapter.getView(), mà tôi mong đợi sẽ quan tâm đến việc thêm nó vào cây xem. – Matthias

+1

Trích dẫn từ tài liệu, "Nếu sai, gốc chỉ được sử dụng để tạo lớp con đúng của LayoutParams cho chế độ xem gốc trong XML". Nếu không, Android không biết cách đính kèm con vào cha mẹ, và vì vậy tôi nghĩ nó sử dụng một LayoutParams rất chung chung. – CommonsWare

1

Tôi sử dụng "AbsListView.LayoutParams" để định cấu hình chiều rộng và chiều cao theo cách thủ công bên trong "Adapter.getView()".

14

Những vấn đề với cách bố trí có thể được gây ra bởi scrollview là wrapper

tôi stumbled khi một số lưu ý trong http://developer.android.com/reference/android/widget/ExpandableListView.html

" ... Lưu ý: Bạn không thể sử dụng wrap_content giá trị cho android: layout_height thuộc tính của một ExpandableListView trong XML nếu kích thước của cha mẹ cũng không được chỉ định nghiêm ngặt (ví dụ, nếu cha mẹ là ScrollView bạn không thể chỉ định wrap_content vì nó cũng có thể là bất kỳ độ dài nào. Tuy nhiên, bạn có thể sử dụng wrap_content nếu cha mẹ ExpandableListView có một kích thước, chẳng hạn như 100 pixel. "

Tôi đã xóa gói ScrollView và bố cục tuyến tính bắt đầu hoạt động bình thường. Bây giờ nó chỉ để hiểu làm thế nào để bọc các công cụ để ScrollView. Chúa giúp tôi

Nhưng dù sao đây thực sự là hành vi kỳ lạ. Tôi nghĩ rằng fill_parent không phải là từ ngữ thực sự chính xác. Khi sử dụng công cụ heirarchyviewer tôi luôn thấy các giá trị WRAP_CONTENT và MATCH_PARENT cho layout_width và leayout_height. Vì vậy, có lẽ fill_parent thực sự có nghĩa là match_parent mà đặt tôi vào sự bất hòa nhận thức.

27

Hãy thử điều này: http://www.java2s.com/Code/Android/UI/setListViewHeightBasedOnChildren.htm

public class Utils { 

    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(); 
    }  
} 
+1

Chào mừng bạn đến với Stack Overflow! Trong khi điều này về lý thuyết có thể trả lời câu hỏi, [nó sẽ là thích hợp hơn] (http://meta.stackexchange.com/q/8259) để bao gồm các phần thiết yếu của câu trả lời ở đây, và cung cấp liên kết để tham khảo. – NullUserException

+1

Bạn chạy phương pháp này ở đâu để sau khi trẻ được làm lại? –

+2

Nice .. Nhưng bạn cần điều này để làm cho 'params.height' tage một giá trị' px' và không phải là giá trị 'dp' ..' int dpValue = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); // dp value float density = context.getResources(). getDisplayMetrics(). mật độ; params.height = (int) Math.ceil (mật độ dpValue *); // giá trị pixel' –

1

Nếu bạn đang sử dụng một tùy chỉnh View trong như mục danh sách đó được thay đổi kích thước, sau đó bạn có thể mất từ ​​câu trả lời PeBek và làm điều này khi bạn xây dựng các View

addOnLayoutChangeListener(
      new OnLayoutChangeListener() { 
       @Override 
       public void onLayoutChange(View _, int __, int ___, int ____, int bottom, int _____, int ______, 
              int _______, int old_bottom) { 
        final ListView list_view = (ListView) getParent(); 
        final ViewGroup.LayoutParams params = list_view.getLayoutParams(); 
        params.height += bottom - old_bottom; 
        list_view.setLayoutParams(params); 
        list_view.requestLayout(); 
       } 
      }); 

Khi View được định lại kích thước phương thức gọi lại này, tôi sẽ chạy và cập nhật chiều cao ListView để bao gồm thay đổi chiều cao (delta botto m). Các giá trị khác, nếu họ chứng minh hữu ích cho bạn là view (ám chỉ đến xem), left, top, right, bottom, old_left, old_top, old_right, old_bottom. Nó hoạt động để mở rộng và thu hẹp chế độ xem.

API 11 là bắt buộc đối với OnLayoutChangeListener, không biết nếu có cách tương thích ngược để làm như vậy.

+0

Lưu ý: addOnLayoutChangeListener() yêu cầu cấp api 11 – larham1

+0

@ larham1 lưu ý, tôi phải bỏ qua điều đó khi tôi viết bài này. –

0

Tôi có cùng một sự cố: tôi muốn có một danh sách bên trong hoạt động của mình làm đầy màn hình khi thiết bị ở dọc theo chiều ngang. tôi giải quyết vấn đề bằng sự tuyến tính Giao diện có chiều cao mà phải fill_parent, và thiết lập chiều cao của mặt hàng đó trong danh sách để 0dp trong khi layout_weight là setter để 1.

android:layout_weight="1" 
android:layout_height="0dp" 
0

làm việc này cho tôi

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 

    android:padding="@dimen/activity_vertical_margin"> 

    <TextView 
     android:id="@+id/tv_status" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:gravity="center" 
     android:textSize="17sp" 
     android:text="@string/text_list_devices" /> 

    <ListView 
     android:id="@+id/lv_paired" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="@dimen/activity_vertical_margin" 
     android:cacheColorHint="#00000000" 
     android:layout_above="@+id/signup_t" 
     android:layout_below="@id/tv_status" 
     /> 

    <Button 

     android:id="@+id/signup_t" 
     style="?android:textAppearanceSmall" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="20dp" 
     android:textColor="@android:color/white" 
     android:layout_alignParentBottom="true" 
     android:text="Print All Records" 
     android:typeface="sans" 
     android:layout_marginLeft="45dp" 
     android:layout_marginRight="45dp" 
     android:textSize="24sp" 
     android:background="@drawable/selector_for_button" 
     android:textStyle="bold" /> 
</RelativeLayout> 
Các vấn đề liên quan