上一篇:Android9编程九:使用RelativeLayout设计登录页面
首先把上一节做的登录页面上再增加一个按钮“注册”,把它的ID设为“buttonRegister”,把它放到登录按钮的下面。效果如图:
然后运行App,然后旋转一下屏幕看看效果。 我的运行效果如图:
注册按钮看不到了!为什么? 显然屏幕的高不够了,内容在纵向上超出了屏幕。于是问题来了:如果屏幕显示不了整个内容怎么办? 答案很简单:“快使用滚动条!吼吼哈嘿!”然而,Layout是没有滚动功能的,要想提供滚动功能,需要使用控件:ScrollView。
ScrollView可以在其儿子的高度超出自己的范围时,在纵向上提供滚动功能。如果想横向滚动的话,请使用另一个View:HorizontalScrollView。但是ScrollView也有自己的要求:只能容纳一个孩子(只生一个好)。
注意ScrollView不同于Layout,所以我们不能用ScrollView代替现在的容器RelativeLayout 。其实我们应该让RelativeLayout成为ScrollView的儿子,然后再让RelativeLayout的高度由其内容决定,也就是由组成登录界面的各子控件来共同决定。
RelativeLayout被放在ScrollView中后,其高度不能再设为match_parent了,因为ScrollView需要跟据其儿子的高度决定是否滚动,如果其儿子的高度如果永远与它的高一样的话,那永远不可能需要滚动。其儿子应体现出内容的高度,这里也就是组成登录功能的控件们所占的高度,所以RelativeLayout的layout_height的值必须为wrap_content。下面我们继续一步步改造。
可以拖一个ScrollView到页面中,如下:
但是,如果你试过了,你会发现这样做不行,呵呵。因为你无法将一个控件拖到页面中作为最外层的控件。此时手动改源码更简单,把页面切换到源码模式,在最外层的元素“”的外面添加标记“”,在RelativeLayout的结束标记“”下面添加ScrollView的结束标记:“”,也就是让ScrollView元素包着RelativeLayout元素。
然后,你还需要把RelativeLayout标记中的一些属性移动到ScrollView标记中。移动哪些呢?看这里(这些属性必须放在最外层的元素中):
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="niuedu.com.andfirststep.MainActivity"
你还要为ScrollView设置宽和高,它既然是最外层的控件,那么就让它充满它的整个爸爸吧(就是Activity了)。现在layout文件的源码变成了这样:
你可以切换回预览模式,你会惊奇的发现现在控件的摆放出问题了:
图像跑到上面去了,控件之间的间距也出了问题。如何修复这些错误呢?
现在选中“RelativeLayout”看一下,你会看到奇怪的现像:虽然它的宽和高都设置成了match_parent,但是它却是“臣妾做不到啊”。注意现在可能在预览中很难选中RelativeLayout,那么就在控件树面板中选吧:
下面是RelativeLayout的宽和高的设置:
ScrollView的内容必须有具体的高度,这样它才能决定是否需要滚动。所以把RelativeLayout的高设置为match_parent不再起作用,其实RelativeLayout的高暗中变成了“wrap_content”。
注意横向上是没问题的,因为ScrollView并不提供横向滚动,所以它的子控件横向上的排版方式跟以前一样。下面我们就把登录界面调整好。怎样调整呢? 现在要让RelativeLayout恰好包着整个内容,那么再让用户名输入框纵向居中就没意义了,我们在设计登录界面时应该改为遵守从上住下依次摆放各控件的原则。
图像在最上面,首先改图像。不再让图像相对于用户名输入框摆放位置,而是让图像位于父控件的顶端,所以把图像控件的属性改成这样:
注意设置了layout_alignParentTop,使得图像控件对齐到了父控件的顶端。用户名输入框应相对于图像控件摆放,位于它下面24dp,所以其属性改成这样:
注意设置了layout_below,取消了layout_centerVertical,密码框和按钮的相对位置没变,不用动。现在页面看起来是下图这样子:
控件之间的位置关系终于正常了。此时运行一下App,旋转到横屏,你会发现界面可以被上下拖动了,右边还出现了滚动条,见图:
其实除了使用ScrollView外,还有一个办法可以解决横屏显示不全的问题,那就是不支持横屏!即固定Activity的方向,这只需要在Manifest文件中搞一下下,见下图:
其实还有一个办法,就是专门创建横屏Layout,见下图:
选择“Create Landscape Variation(创建风景画变体)”,会当前Layout添加一个新的资源文件,当屏幕改为横屏时,App会自动加载这个横屏的Layout资源。
landscape 是风景画的意思,油画中风景画都是宽的,用它来代表横屏。竖屏是portrait,肖像画,肖像画都是长的,用它来代表竖屏。
贴一下源码吧:
添加新的Layout资源,其实就是往合适的文件夹下添加一个XML文件,当然我们应该借助Android Studio提供的工具而尽量不要手动去做。具体做法是:在res/layout组上点出右键菜单,如下图:
然后选择New–Layout resource file,出现新建资源对话框:
在“File name”项中输入layout文件的名字,将来也是这个资源的ID,所以要注意其规则,不能以数字开头,单词之间推荐用下划线分隔(非必须,但最好遵守)。
“Root element”项中输入这个Layout的根控件,即某个Layout控件。在这里我们使用一个新的Layout:FrameLayout。
“Source set”有三个选项:main、release、debug。Debug指的是带有调试信息的App版本;Release是没有调试信息的App版本;这里指的是分别包含在Debug、Release版中的代码和资源,即可以指定某些文件只在Release版中起作用,有些只在Debug版中起作用。而属于main的文件在两者中都起作用。这里一般就选main。
“Directory name”:所在文件夹的名字,这个不要变了,必须在layout下。
下面的不用选。点OK即可。
(摘自《Android9编程通俗演义》-清华大学出版社,京东淘宝及各大书店有售)