2014-09-12 26 views
7

Tôi tăng lượt xem này và thêm nó vào ListView làm tiêu đề. Tôi cố gắng để làm cho nó 500dp cao (cứng mã hóa, vì lợi ích của ví dụ này)Tiêu đề ListView bỏ qua layout_height

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" 
       android:layout_width="match_parent" android:background="@drawable/repeat_background" 
       android:layout_height="500dp"> 

    <ImageView android:id="@+id/filter_menu" android:src="@drawable/ic_sort" 
       android:layout_gravity="center_vertical" android:padding="8dp" 
       android:layout_weight="0" 
       android:layout_width="wrap_content" android:layout_height="wrap_content" 
       android:onClick="showPopup"/> 

</LinearLayout> 

Các ListView không tôn trọng authoritah header của nó và kết thúc tốt đẹp nó trên nội dung của nó. Bất cứ ai có thể vui lòng giải thích những gì sẽ xảy ra?

Trả lời

12

Chìa khóa để hiểu những gì đang xảy ra là tìm hiểu cách các đầu trang và chân trang của ListView được triển khai. Chúng là một thủ thuật: thời điểm bạn thêm đầu trang hoặc chân trang đầu tiên vào ListView của bạn, ListAdapter của bạn được bao bọc trong một HeaderViewListAdapter (xảy ra trên line 270 of ListView.java). HeaderListViewAdapter là một bộ điều hợp danh sách điều chỉnh các giá trị countposition để bao gồm đầu trang và chân trang; đầu trang và chân trang trở thành các mục danh sách bình thường mà hệ thống quản lý cho bạn.

Nếu bạn xem line 207 of HeaderListViewAdapter.java, bạn sẽ thấy rằng triển khai getView bỏ qua chế độ xem parent khi thêm đầu trang hoặc chân trang. Điều này có hiệu lực là mLayoutParams của nó không được khởi tạo từ XML (có thể không thực sự trỏ bạn đến mã nguồn, chỉ là một cái gì đó tôi đã phát hiện ra theo thời gian).

Nếu bạn sau đó làm theo các các cuộc gọi đến getView cho một chút, quá khứ line 2237 of AbsListView.java, và làm theo lời kêu gọi obtainView cho một chút và tìm kiếm LayoutParams (đó là những gì tôi chỉ làm) bạn kết thúc tại line 1182 of ListView.java. Ở đây bạn thấy rằng, nếu params bố trí null khi nhìn đứa trẻ được đo, nó gọi ra generateDefaultLayoutParams(), được thực hiện trên line 6065 of AbsListView.java:

@Override 
protected ViewGroup.LayoutParams generateDefaultLayoutParams() { 
    return new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 
     ViewGroup.LayoutParams.WRAP_CONTENT, 0); 
} 

... và đó là nơi WRAP_CONTENT của bạn đến từ .

Là một công việc dễ dàng, chỉ cần quấn <LinearLayout/> của XML của bạn bên trong một <FrameLayout/>. Giữ 500dp trên LinearLayout và làm cho FrameLayout có chiều cao bố trí của WRAP_CONTENT (sẽ bị bỏ qua).

+1

+1 để có câu trả lời phức tạp. Tôi không biết phải nghĩ gì về điều này; lỗi - hoặc tính năng? Sự trừu tượng, hoặc mô hình tâm thần bị phá vỡ khi mọi thứ không hoạt động như mong đợi. –

+0

tuyệt vời, cảm ơn! – kiruwka

Các vấn đề liên quan