RelativeLayout

来源:互联网 发布:win7网络连接图标没了 编辑:程序博客网 时间:2024/06/05 07:40

抢占空间

我们都知道LinearLayout可以用width=0,weight=1来抢占剩余空间

RelativeLayout也可以,比如下面的布局通过layout_alignParentLeft和layout_toLeftOf来定位,这里的layout_width是match_parent,其实改为0dp也可以的。效果一样

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity">    <TextView        android:id="@+id/text"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:text="@string/hello_world" />    <View        android:layout_width="match_parent"        android:layout_height="20dp"        android:layout_alignParentLeft="true"        android:layout_toLeftOf="@id/text"        android:background="#ff0000"></View></RelativeLayout>



垂直居中

Relativelayout内部元素一般有2种垂直居中方法,一种是在RelativeLayout上写    android:gravity="center_vertical",另一种是在元素内部写layout_centerVertical,(注意android:layout_gravity="center_vertical"是无效的). 两种方法效果不一样的,推荐第二种。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#ff0000"    android:gravity="center_vertical"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity">    <ImageView        android:id="@+id/smile"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@drawable/smile" />    <ImageView        android:layout_width="50dp"        android:layout_height="50dp"        android:layout_toRightOf="@id/smile"        android:src="@drawable/ali" /></RelativeLayout>


第二种
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#ff0000"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity">    <ImageView        android:id="@+id/smile"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerVertical="true"        android:src="@drawable/smile" />    <ImageView        android:layout_width="50dp"        android:layout_height="50dp"        android:layout_centerVertical="true"        android:layout_toRightOf="@id/smile"        android:src="@drawable/ali" /></RelativeLayout>



层叠效果

以下代码可以让RelativeLayout产生层叠效果,类似FrameLayout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity">    <View        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="#ff0000"></View>    <TextView        android:background="#00ff00"        android:layout_centerInParent="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/hello_world" /></RelativeLayout>

带间距的居中


想实现上图的效果,在一个大的view中去掉30个dp,然后垂直居中,没什么简单的方法,必须中间插一个,代码如下

   <RelativeLayout        android:id="@+id/like_layout"        android:layout_width="100dp"        android:layout_height="100dp"        android:layout_centerVertical="true"        android:background="#ff0000">        <RelativeLayout            android:layout_width="match_parent"            android:layout_height="match_parent"            android:layout_marginTop="30dp">            <TextView                android:background="#00ff00"                android:id="@+id/like_text"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_centerVertical="true"                android:textSize="10sp" />        </RelativeLayout>    </RelativeLayout>

wrapContent时候不听话

需求:想实现一个相对布局,布局的宽度由里面的内容决定,里面放2个内容,一个居左,一个居右

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity">    <TextView        android:id="@+id/hello"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/hello_world" />    <RelativeLayout        android:id="@+id/mylayout"        android:layout_below="@id/hello"        android:layout_width="wrap_content"        android:layout_height="100dp"        android:background="#ff0000">        <TextView            android:id="@+id/text1"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentLeft="true"            android:text="第一" />        <TextView            android:layout_alignParentRight="true"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_toRightOf="@id/text1"            android:text="第二" />    </RelativeLayout></RelativeLayout>

 

我写了上述代码,主要内容是mylayout这个相对布局,里面2个元素,一个text1居左,一个text2居右,并且设置了text2是在text1的右边,表面看来没问题,mylayout的宽度应该就是text1和text2的宽度,但是实际情况并非如此,结果如下:

  


哪里出了问题,如何解决?
解决方案很简单,只要把 android:layout_alignParentRight="true"这句话去掉就可以了,原因估计是layout_alignParentRight存在的话layout_toRightOf这些就失效了,具体原因还得看源码,我暂时未看。
结论,用了layout_alignParent***之后就不要用layout_to**Of了,定位的东西有一个就够了

删除那句代码之后,效果如下,达到了预期效果。但是注意,还是隐患的哦,请往下看。


接着,我在“第二”这个textview上加了一句话,android:layout_marginRight="10dp",然后就发生了下面的问题

      


在不同的手机上效果居然不一样,第一张是nexus 5x ,6.0的系统,第二章是coolpad9970,4.2.2的系统。

看来是不同系统的实现方法不一样哦,很明显在计算父窗口宽的时候,不同系统表现不一样

所以说,这种需求最好用Linearlayout而不是RelativeLayout,即使在某些版本看来没问题

toleft一个gone的view

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.fish.a.MainActivity">    <TextView        android:id="@+id/a"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:background="#ff0000"        android:text="Hello World!"        android:visibility="gone" />    <TextView        android:id="@+id/b"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_toLeftOf="@id/a"        android:background="#00ff00"        android:text="Hello meeeee!" /></RelativeLayout>

如上xml所示的,最终b会在哪个位置呢? a靠右为gone,b在a的左边,本来以为最后b会靠右,结果发现不对,a gone调了,b会跑到左边去。

要想实现b也是靠右的,那么要用个RelativeLayout包起来,设置这个RelativeLayout靠右才行。如下图所示。

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.fish.a.MainActivity">    <RelativeLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true">        <TextView            android:id="@+id/a"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:background="#ff0000"            android:text="Hello World!"            android:visibility="gone" />        <TextView            android:id="@+id/b"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_toLeftOf="@id/a"            android:background="#00ff00"            android:text="Hello meeeee!" />    </RelativeLayout></RelativeLayout>

一个靠右需求的坑

需求1,一个文本a靠右对齐,a可能显示,也可能不显示

于是我写了下边的代码,非常简单,a显示不显示只要改变a的visibility就可以了

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.fish.a.MainActivity">    <TextView        android:id="@+id/a"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:background="#ff0000"        android:text="aaaaaaaa"        android:visibility="visible" />   </RelativeLayout>

显示效果如下:



需求2,在a的左边加一个b文本,b也是可能显示,可能不显示的

于是我在上述代码的基础上改了

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.fish.a.MainActivity">    <TextView        android:id="@+id/a"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:background="#ff0000"        android:text="aaaaaaaa"        android:visibility="visible" />    <TextView        android:id="@+id/b"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_toLeftOf="@id/a"        android:layout_marginLeft="15dp"        android:background="#00ff00"        android:text="bbbbbbb" /></RelativeLayout>
看上去很简单,显示效果如下


但是此时其实已经有bug了。

此时的完整需求应该是,a和b都可能显示或者不显示,如果只显示一个那这个靠右显示,如果2个显示,那么a靠右,b在a的左边显示。

但是此时如果a不显示,b要显示,b会左对齐。如下图所示。


怎么办呢?可以用个RelativeLayout包起来,设置这个RelativeLayout靠右,代码如下所示:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.fish.a.MainActivity">    <RelativeLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true">        <TextView            android:id="@+id/a"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:background="#ff0000"            android:text="aaaaaaaa"            android:visibility="gone" />        <TextView            android:id="@+id/b"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_toLeftOf="@id/a"            android:background="#00ff00"            android:text="bbbbbbb" />    </RelativeLayout></RelativeLayout>

表面看起来加一个RelativeLayout解决了此问题,但是其实不然,这不一个好方法。

第三个需求很快就来了,要在a,b的左边填满蓝色.

写出代码如下

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.fish.a.MainActivity">    <RelativeLayout        android:id="@+id/group"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true">        <TextView            android:id="@+id/a"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:background="#ff0000"            android:text="aaaaaaaa"            android:visibility="gone" />        <TextView            android:id="@+id/b"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_toLeftOf="@id/a"            android:background="#00ff00"            android:text="bbbbbbb"            android:visibility="visible" />    </RelativeLayout>    <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_toLeftOf="@id/group"        android:background="#0000ff" /></RelativeLayout>


这个时候若a不显示,b显示,那没问题.但是只要a显示,那就有问题。ab一起显示也有问题。

   

什么原因呢?只要a显示,a是layout_alignParentRight,那么group的wrap_content就会失效,变为mach_parent。

如何解决问题呢?主要问题在于,第二部处理需求2的时候,不该用RelativeLayout把2个view包起来,用个LinearLayout就可以了。

代码如下:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.fish.a.MainActivity">    <LinearLayout        android:id="@+id/group"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true">        <TextView            android:id="@+id/b"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="#00ff00"            android:text="bbbbbbb"            android:visibility="visible" />        <TextView            android:id="@+id/a"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="#ff0000"            android:text="aaaaaaaa"            android:visibility="visible" />    </LinearLayout>    <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_toLeftOf="@id/group"        android:background="#0000ff" /></RelativeLayout>

效果如下

    

写代码的时候经常一步一步来,每一步表面看起来是好的,可是回头一看,可能已经存在隐患了,还是要多思考,会不会带来别的问题。


结论

对于RelativeLayout内部的元素,
可以同时使用toleftof和torightof
如果RelativeLayout的大小可以确定,那内部某元素就能一起用aligin_parent_left和toleftof (同样align_parent_right和torightof);如果RelativeLayout的大小不确定,那内部某元素就不要一起用aligin_parent_left和toleftof ,避免“wrap_content不听话”的问题

0 0