2016-05-13 104 views
0

Related question。答案:RelativeLayout無法做到這一點。無論如何,我正在問怎麼做,而不是只是 RL,或與其他東西。如何將視圖(如在RelativeLayout中)與侄子視圖對齊?

一般故事:您有一個難以調整的複雜佈局,並且隨之而來的是添加內容的請求,與嵌套視圖對齊。
enter image description here

什麼是最佳方法?具有自定義樣式的彈出窗口? (還不熟悉)?花幾天時間將整個層次結構更改爲單個RelativeLayout?作爲包裝的自定義佈局類?
AbsoluteLayout(不建議使用)或FrameLayout以編程方式更改LayoutParams或邊距? (這個我寧願避免,我更喜歡不要觸及Measure等)

簡單示例(與上面的圖無關):
LinearLayout定義元素的相對高度。我不知道用RelativeLayout來做。
anExpandableView是從someBar(此處爲全寬度,但可能需要對齊其寬度以及垂直位置)滑動時的動畫。

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:animateLayoutChanges="true"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical"> 

     <include 
      android:id="@+id/topStuff" 
      layout="@layout/incl_topstuff" 
      android:layout_width="match_parent" 
      android:layout_weight="7" 
      android:layout_height="0dip" /> 

     <include 
      android:id="@+id/someBar" 
      layout="@layout/incl_filters_and_stuff" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 

     <include 
      android:id="@+id/bottomStuff" 
      layout="@layout/incl_bottomstuff" 
      android:layout_width="match_parent" 
      android:layout_height="0dip" 
      android:layout_weight="10" /> 

    </LinearLayout> 

    <include 
     android:id="@+id/anExpandableView" 
     layout="@layout/incl_filters" 
     android:visibility="gone" 
     android:layout_below="@id/someBar"/> 

</RelativeLayout> 

我知道,所以有一個討厭的一般性問題,但我不希望有一個臨時的解決方案。我在問如果只有包裝RelativeLayout允許與不是直接兄弟的視圖對齊,那麼可以解決的情況下要做什麼。

+0

也許你可以提供一個你希望你的視圖看起來像什麼的圖表... – Elye

+0

我知道它,對特定情況的需求。不,我拒絕。我想做'layout_alignBottom'或'layout_below'等等,引用不是兄弟視圖,而是嵌套更深的東西。我使用了'include',因爲它並不關心視圖是什麼,只有'anExpandableView'需要自己定位。如果你理解困難,請指出不清楚的部分。 – kaay

+0

第一句話本身已經非常具有說服力,「你有一個複雜的佈局,並且一直要求添加一些東西,與嵌套視圖對齊。」複雜佈局是什麼意思?一個視圖可以被認爲是嵌套的或者不依賴於它使用的佈局......因此如果沒有適當的上下文,很難理解這個問題。如果「一個」圖表能夠讓我們給出一個剛性的答案,也許你可以提供2個或更多的圖來描述總體思路。 – Elye

回答

1

簡單來說,RelativeLayout只能測量和佈局基於對方的直接孩子,但我想你已經知道了。

唯一的一般解決方案是實現您自己的自定義佈局類,我不會推薦。如果我不得不猜測爲什麼RelativeLayout不能遍歷整個佈局層次結構,它可能是出於性能原因。

不幸的是,如果您使用RelativeLayouts和LinearLayouts,並且您希望視圖依賴於其他視圖,則必須選擇一種方法並堅持使用RelativeLayout的平面層次結構或LinearLayout的嵌套層次結構。

根據你的例子,據我所知,沒有辦法用RelativeLayout實現加權視圖,所以你堅持使用LinearLayout。

最簡單的做法是在代碼中展開您的expandableView,將它與RelativeLayout的底部對齊,根據bottomStuff設置它的高度和位置,然後從那裏設置動畫。

如果你真的想在xml中做到這一點,我可以想到一個有點怪異的臨時方法,但可以通過一些工作來泛化任何層次結構的度量和佈局。

創建一個平行但不可見的LinearLayout,它是第一個同級的兄弟。給它一個空白的視圖,頂部有7個重量,中間是someBar的不可見副本,然後是重量爲10的可展開視圖。要讓它向上滑動,要麼爲不可見的someBar的高度設置動畫,要麼爲空的重量查看頂部朝0,或刪除它們/設置它們消失,並在LinearLayout上設置animateLayoutChanges。

+0

謝謝。回覆:「選擇一種方法」 - 「LinearLayout」無法對齊。 'RelativeLayout'不能做權重。我需要一點。現在,我使視圖「消失」,並以編程方式設置邊距。你知道獲取視圖座標的更好方法,而不是遞歸添加視圖和每個祖先的getTop()的值嗎? – kaay

+0

順便說一句,我不認爲性能是原因。 findViewByID非常頻繁地完成,我還沒有看到任何人關心優化它。更可能的是避免循環引用。 – kaay

+1

您可以使用View.getGlobalVisibleRect並從您希望座標相關的父視圖中偏移它,或從rect中獲取視圖的大小,而不是遞歸添加相對偏移量。然後通過RelativeLayout.LayoutParams設置高度和寬度。我不確定你爲什麼要設置邊距,而不是直接設置高度或位置。 具體來說,在bottomStuff上使用View.getGlobalVisibleRect,從rect頂部和底部獲取高度,並將其設置爲expandableView的高度,並將expandableView設置爲alignParentBottom。 –

相關問題