2013-06-15 44 views
11

Tôi có hai chế độ xem trong bố cục. Tôi sẽ gọi chúng lần lượt là View AView B.MATCH_PARENT nếu chế độ xem anh chị em lớn hơn, WRAP_CONTENT nếu chế độ xem anh chị em nhỏ hơn

┌──────┐ 
│┌─┐┌─┐│ 
││A││B││ 
│└─┘└─┘│ 
└──────┘ 

Chiều cao của bố trí cha mẹ (bao gồm View AView B) là WRAP_CONTENT.

Ở đây, chiều cao View BWRAP_CONTENT. Đó là, chiều cao của nó có thể được thay đổi liên quan đến nội dung của nó.

Những gì tôi muốn làm là

  1. 'chiều cao s để View B' Set View A s chiều cao nếu View A 'nội dung s là ngắn hơn View B' nội dung s.
  2. Đặt chiều cao của nội dung là View A nếu nội dung của View A cao hơn nội dung của View B.

Vì vậy,

① Nếu nội dung của View B là cao, sau đó View A 's chiều cao được thiết lập để View B' chiều cao s.

 ┌──────┐  ┌──────┐ 
     │┌─┐┌─┐│  │┌─┐┌─┐│ 
     ││ ││ ││  ││A││ ││ 
I want ││A││B││, not │└─┘│B││. 
     ││ ││ ││  │ │ ││ 
     │└─┘└─┘│  │ └─┘│ 
     └──────┘  └──────┘ 

② Nếu nội dung của View B là ngắn hơn, sau đó View A 's chiều cao là View A' chiều cao của riêng conent của.

 ┌──────┐  ┌──────┐ 
     │┌─┐┌─┐│  │┌─┐┌─┐│ 
     ││ ││B││  ││A││B││ 
I want ││A│└─┘│, not │└─┘└─┘│. 
     ││ │ │  └──────┘ 
     │└─┘ │ 
     └──────┘ 

Nếu phụ huynh là LinearLayout (Horizontal), thiết View A 'chiều cao s để WRAP_CONTENT vi phạm trường hợp 1, và thiết lập View A' chiều cao s để MATCH_PARENT làm hại chính trường hợp 2.

Nếu phụ huynh là RelativeLayout, thiết View A để gắn kết cả hai vi phạm trên cùng và dưới cùng của cha mẹ của nó là điều kiện của RelativeLayout: Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children. For example, you cannot have a RelativeLayout whose height is set to WRAP_CONTENT and a child set to ALIGN_PARENT_BOTTOM.

Làm cách nào để giải quyết vấn đề này?

Trả lời

6

Có nhiều cách khác nhau để thực hiện việc này, ví dụ bằng cách tạo tùy chỉnh riêng của bạn ViewGroup, có thể dựa trên số ngang LinearLayout. Tuy nhiên, tôi cho rằng giải pháp đơn giản nhất sẽ là thiết lập động các yêu cầu trong thời gian chạy.

xem xét bố trí sau đây chỉ với hai TextView s trong một ngang LinearLayout:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/container" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:background="#f00" 
    android:padding="10dp" > 

    <TextView 
     android:id="@+id/first" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="#0f0" 
     android:padding="5dp" 
     android:text="One line" /> 

    <TextView 
     android:id="@+id/second" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="#00f" 
     android:padding="5dp" 
     android:text="Two\nlines" 
     android:textColor="#fff" /> 

</LinearLayout> 

Cả hai quấn chiều cao của họ, mà về cơ bản phù hợp với những yêu cầu đầu tiên của bạn.

Bây giờ yêu cầu 2: cho mục đích trình diễn, tôi đã phá vỡ văn bản thứ hai của TextView thành hai dòng, để làm cho nó cao hơn văn bản đầu tiên. Để thực hiện các TextView trận đấu đầu tiên đó là chiều cao, tất cả các bạn phải làm là thế này:

LinearLayout container = (LinearLayout) findViewById(R.id.container); 
final TextView first = (TextView) findViewById(R.id.first); 
final TextView second = (TextView) findViewById(R.id.second); 

container.post(new Runnable() { 
    @Override public void run() { 
     int h1 = first.getMeasuredHeight(); 
     int h2 = second.getMeasuredHeight(); 
     if (h1 < h2) first.getLayoutParams().height = h2; 

    } 
}); 

Các 'lừa' là để gửi đến hàng đợi của xem, đảm bảo logic sẽ không được thực hiện cho đến khi trẻ em đã được đo và có chiều cao hợp lệ. Đối với yêu cầu 2, chiều cao của chế độ xem đầu tiên sẽ chỉ phải thay đổi nếu chế độ xem thứ hai cao hơn, chính xác là phần của phương thức run().

+0

Không có cách nào để thực hiện điều này? Nếu không, tôi sẽ phải làm điều này bên trong bộ điều hợp của tôi bởi vì tôi muốn làm một cái gì đó như thế này bên trong một danh sách đầy tự động. –

+1

@BartBurg: Một 'ViewGroup' tùy chỉnh có lẽ sẽ là giải pháp tối ưu nhất. Việc mở rộng 'LinearLayout' sẽ là một khởi đầu tốt và - tùy thuộc vào trường hợp sử dụng cụ thể của bạn - tất cả những gì bạn cần làm là ghi đè' onMeasure() 'để xem xét các tiêu chí được nêu ở trên. –

+0

Nó gây ra một hiệu ứng hoạt hình, có thể không mong muốn. Một mẫu ViewGroup tùy chỉnh sẽ được đánh giá cao. –

1

Bạn cần đặt thứ nguyên của chế độ xem theo lập trình sử dụng thông số bố cục. Giả sử rằng bạn đang sử dụng một LinearLayout giữ quan điểm đây là những gì bạn sẽ làm gì:

//the views are called a and b 
LinearLayout.LayoutParams aParams = a.getLayoutParams(); 
LinearLayout.LayoutParams bParams = b.getLayoutParams(); 
int aWidth = aParams.width; 
int aHeight = aParams.height; 
int bWidth = bParams.width; 
int bHeight = bParams.height; 
if (aHeight >= bHeight) { 
    // do nothing 
} 
else { 
    a.setLayoutParams(new LinearLayout.LayoutParams(aWidth, bHeight)); 
} 

Khi bạn thiết lập chiều cao của họ ban đầu giữ chúng như wrap_content trong xml, trước khi sửa đổi này.

0

Điều này có thể được giải quyết rất dễ dàng, chỉ từ axml.

Giữ chiều cao của bố cục mẹ là wrap_content và đặt chiều cao của mỗi chế độ xem của con là match_parent. Điều này sẽ làm cho chiều cao của bố cục mẹ được bao bọc thành con cao nhất và chiều cao của mỗi chế độ xem con sẽ kéo dài đến cha mẹ.

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="horizontal" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"> 
    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="text" /> 
    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:text="More\ntext" /> 
</LinearLayout> 
Các vấn đề liên quan