2016-05-13 113 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。 –

相关问题