如何将视图(如在RelativeLayout中)与侄子视图对齐?
Related question。答案:RelativeLayout无法做到这一点。无论如何,我正在问怎么做,而不是只是 RL,或与其他东西。如何将视图(如在RelativeLayout中)与侄子视图对齐?
一般故事:您有一个难以调整的复杂布局,并且随之而来的是添加内容的请求,与嵌套视图对齐。
什么是最佳方法?具有自定义样式的弹出窗口? (还不熟悉)?花几天时间将整个层次结构更改为单个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
允许与不是直接兄弟的视图对齐,那么可以解决的情况下要做什么。
简单来说,RelativeLayout只能测量和布局基于对方的直接孩子,但我想你已经知道了。
唯一的一般解决方案是实现您自己的自定义布局类,我不会推荐。如果我不得不猜测为什么RelativeLayout不能遍历整个布局层次结构,它可能是出于性能原因。
不幸的是,如果您使用RelativeLayouts和LinearLayouts,并且您希望视图依赖于其他视图,则必须选择一种方法并坚持使用RelativeLayout的平面层次结构或LinearLayout的嵌套层次结构。
根据你的例子,据我所知,没有办法用RelativeLayout实现加权视图,所以你坚持使用LinearLayout。
最简单的做法是在代码中展开您的expandableView,将它与RelativeLayout的底部对齐,根据bottomStuff设置它的高度和位置,然后从那里设置动画。
如果你真的想在xml中做到这一点,我可以想到一个有点怪异的临时方法,但可以通过一些工作来泛化任何层次结构的度量和布局。
创建一个平行但不可见的LinearLayout,它是第一个同级的兄弟。给它一个空白的视图,顶部有7个重量,中间是someBar的不可见副本,然后是重量为10的可展开视图。要让它向上滑动,要么为不可见的someBar的高度设置动画,要么为空的重量查看顶部朝0,或删除它们/设置它们消失,并在LinearLayout上设置animateLayoutChanges。
谢谢。回复:“选择一种方法” - “LinearLayout”无法对齐。 'RelativeLayout'不能做权重。我需要一点。现在,我使视图“消失”,并以编程方式设置边距。你知道获取视图坐标的更好方法,而不是递归添加视图和每个祖先的getTop()的值吗? – kaay
顺便说一句,我不认为性能是原因。 findViewByID非常频繁地完成,我还没有看到任何人关心优化它。更可能的是避免循环引用。 – kaay
您可以使用View.getGlobalVisibleRect并从您希望坐标相关的父视图中偏移它,或从rect中获取视图的大小,而不是递归添加相对偏移量。然后通过RelativeLayout.LayoutParams设置高度和宽度。我不确定你为什么要设置边距,而不是直接设置高度或位置。 具体来说,在bottomStuff上使用View.getGlobalVisibleRect,从rect顶部和底部获取高度,并将其设置为expandableView的高度,并将expandableView设置为alignParentBottom。 –
也许你可以提供一个你希望你的视图看起来像什么的图表... – Elye
我知道它,对特定情况的需求。不,我拒绝。我想做'layout_alignBottom'或'layout_below'等等,引用不是兄弟视图,而是嵌套更深的东西。我使用了'include',因为它并不关心视图是什么,只有'anExpandableView'需要自己定位。如果你理解困难,请指出不清楚的部分。 – kaay
第一句话本身已经非常具有说服力,“你有一个复杂的布局,并且一直要求添加一些东西,与嵌套视图对齐。”复杂布局是什么意思?一个视图可以被认为是嵌套的或者不依赖于它使用的布局......因此如果没有适当的上下文,很难理解这个问题。如果“一个”图表能够让我们给出一个刚性的答案,也许你可以提供2个或更多的图来描述总体思路。 – Elye