RelativeLayout

抢占空间

我们都知道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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值