android UI适配简单记录二

要想了解UI适配,首先需要了解android中的布局类。
android中有六大布局

1.LinearLayout
2.RelativeLayout
3.FrameLayout
4.GridLayout
5.TableLayout
6.AbsoluteLayout
1.LinearLayout
package android.widget;
public class LinearLayout extends ViewGroup

2.RelativeLayout
package android.widget;
public class RelativeLayout extends ViewGroup 

3.FrameLayout
package android.widget;
public class FrameLayout extends ViewGroup 

4.GridLayout
package android.widget;
public class GridLayout extends ViewGroup

5.TableLayout
package android.widget;
public class TableLayout extends LinearLayout 

6.AbsoluteLayout 
在api3中废弃。
package android.widget;
public class AbsoluteLayout extends ViewGroup 

6个类都在package android.widget下,其中5个继承自ViewGroup ,TableLayout 继承自LinearLayout 。

还有一个新的布局类ConstraintLayout。这个是目前为止比较新的,android studio新建的项目一般都默认生成ConstraintLayout。这个放到最后。

布局定义用户界面的视觉结构,如Activity应用小部件的 UI。您可以通过两种方式声明布局:

  • 在 XML 中声明 UI 元素。Android 提供了对应于 View 类及其子类的简明 XML 词汇,如用于小部件和布局的词汇;
  • 运行时实例化布局元素。您的应用可以通过编程创建 View 对象和 ViewGroup 对象(并操纵其属性)。

首先,来看看常见布局LinearLayout和RelativeLayout。


常见布局
常见布局有以下两种(网页视图先忽略不计)。
线性布局
一种使用单个水平行或垂直行来组织子项的布局。它会在窗口长度超出屏幕长度时创建一个滚动条。

相对布局
让您能够指定子对象彼此之间的相对位置(子对象 A 在子对象 B 左侧)或子对象与父对象的相对位置(与父对象顶部对齐)。

简单来说,界面中控件数量少,相对位置没有那么复杂的就是要线性布局,布局相对复杂的需要使用相对布局,因为复杂的情况下如果用线性布局的话需要嵌套更多。

以下面2个xml布局文件为例,简单看一下LinearLayout 和 RelativeLayout之间的差异。

如果xml布局使用LinearLayout。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingLeft="16dp"
    android:paddingRight="16dp">

    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/reminder" />

   <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Spinner
            android:id="@+id/dates"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="3" />

        <Spinner
            android:id="@id/times"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>
    </LinearLayout>
    <Button
        android:layout_width="96dp"
        android:layout_height="wrap_content"
        android:text="@string/done"
        android:layout_gravity="end"/>
</LinearLayout>

预览图如下


image.png

如果xml布局使用RelativeLayout。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="16dp"
    android:paddingRight="16dp" >
    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/reminder" />
    <Spinner
        android:id="@+id/dates"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/name"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/times" />
    <Spinner
        android:id="@id/times"
        android:layout_width="96dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/name"
        android:layout_alignParentRight="true" />
    <Button
        android:layout_width="96dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/times"
        android:layout_alignParentRight="true"
        android:text="@string/done" />
</RelativeLayout>

预览图如下


image.png

由于LinearLayout和RelativeLayout属性不一样,具体写法略有差异,具体属性如果不熟悉不必纠结,先记着就行用多了就会,看一两次也很难记下来,并且component tree不一样,使用RelativeLayout的情况下嵌套了一层,使用LinearLayout的情况下最多嵌套了2层。

以下为官方文档推荐。

尽管您可以通过将一个或多个布局嵌套在另一个布局内来实现您的 UI 设计,但应该使您的布局层次结构尽可能简略。布局的嵌套布局越少,绘制速度越快(扁平的视图层次结构优于深层的视图层次结构)。

至此,对 在XML 中声明 UI 元素的方式有了一定的了解,现在来看运行时实例化布局元素这种方式。

以下文字出处: android编程权威指南

通常是通过布局文件创建视图的,其实也可以在代码里创建视图。
实际上,可以完全不用创建布局文件,以代码的方式创建布局。

以代码的方式创建视图很简单:调用视图类的构造方法,并传入Context参数。不创建任何布局文件,用代码就能创建完整的视图层级机构。

将代码改为如下所示。

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     //   setContentView(R.layout.activity_main);
        TextView textView = new TextView(this);
        textView.setText("test");
        textView.setTextSize(100);
        setContentView(textView);
    }
}

运行结果如下所示。


以上只是简单示例,实际使用中,可以xml+代码 2种方式结合使用。

至此,对LinearLayout、RelativeLayout以及声明布局的两种方式都有了一定的了解,接着来看android中的六大布局中的其余4个。

下面来看FrameLayout。
FrameLayout是最简单的ViewGroup组件,它不以特定方式安排其子视图的位置。FrameLayout子视图的位置排列取决于它们各自的android:layout_gravity属性。
官方定义:
FrameLayout is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that's scalable to different screen sizes without the children overlapping each other. You can, however, add multiple children to a FrameLayout and control their position within the FrameLayout by assigning gravity to each child, using the android:layout_gravity attribute.

Android FrameLayout (帧布局) 直接在屏幕上开辟出一块空白的区域,当我们往里面添加控件的时候,会默认把它们放到这块区域的左上角
FrameLayout (帧布局) 有点类似于把零散的大小不一的纸按左上角对齐的方式定成一本书一样。


image.png

定义如下所示xml。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:text="test1"
        android:textSize="50sp"
        android:background="#ff0000" />
    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:text="test2"
        android:textSize="30sp"
        android:background="#00ff00" />

</FrameLayout>

运行结果如下所示。


n.png

由于FrameLayout的子视图仅仅取决于它们各自的android:layout_gravity属性。,因此修改布局文件中的android:layout_gravity属性。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:text="test1"
        android:layout_gravity="center"
        android:textSize="50sp"
        android:background="#ff0000" />
    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:text="test2"
        android:layout_gravity="bottom|end"
        android:textSize="30sp"
        android:background="#00ff00" />

</FrameLayout>

修改后运行结果如下所示。

n.png

至于FrameLayout应用场景,常见的就是fragment。
通用的布局定义文件activity_fragment.xml.该布局提供了一个用来放置fragment的FrameLayout容器视图。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

接下来就是GridLayout了。

基本概念
GridLayout把页面分成m行和n列,使用m+1条线和n+1条线,把页面共分成n*m个Cell。指定位置时行坐标是从0到m,列坐标是从0到n。每一个子View占一个或多个Cell。比如(0, 0)到(0, 1)就是占第一个Cell的区域。(0, 0), (0, 2)就是占第一行的2个Cell的区域(横向拉伸).

下面以GridLayout 布局经典计算器为例,看看基本使用,不做深入。

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:columnCount="4"
    android:orientation="horizontal"
    android:rowCount="6" >

    <TextView
        android:layout_columnSpan="4"
        android:layout_gravity="fill"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:background="#dddddd"
        android:text="0"
        android:textSize="50sp" />

    <Button
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:text="清空" />

    <Button
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:text="回退" />

    <Button android:text="1" />

    <Button android:text="2" />

    <Button android:text="3" />

    <Button android:text="+" />

    <Button android:text="4" />

    <Button android:text="5" />

    <Button android:text="6" />

    <Button android:text="-" />

    <Button android:text="7" />

    <Button android:text="8" />

    <Button android:text="9" />

    <Button android:text="*" />

    <Button android:text="0"
        android:layout_columnSpan="2"
        android:layout_gravity="fill" />

    <Button
        android:layout_width="wrap_content"
        android:text="." />

    <Button android:text="/" />

</GridLayout>
image.png

实际上,GridLayout布局的关键点在于GridLayout中的android:columnCount="4" 和 android:rowCount="6" 设置好网格的最大行数和列数以及子视图的android:layout_columnSpan以及android:layout_gravity属性。

下面来看看TableLayout。
TableLayout 是一种可以制作表格的布局,它和 GridLayout 的区别是 GridLayout 只能制定每一列宽度一样的表格布局,而 TableLayout 能够制定各列宽度不一样的表格布局。
来看看TableLayout 3个常用属性。

1.android:collapseColumns:设置需要被隐藏的列的序号
2.android:stretchColumns:设置运行被拉伸的列的列序号
3.android:shrinkColumns:设置允许被收缩的列的列序号

1.TableLayout中添加以下属性: android:collapseColumns = "0,2",就是隐藏第一与第三列。

<TableLayout android:id="@+id/TableLayout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:collapseColumns="0,2"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="one" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="two" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="three" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="four" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="five" />
       
    </TableRow>
</TableLayout>

预览图如下。


image.png

2.TableLayout中添加以下属性: android:stretchColumns = "1"设置第二列为可拉伸列,让该列填满这一行所有的剩余空间。

<TableLayout android:id="@+id/TableLayout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:stretchColumns="1"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="one" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="two" />

    </TableRow>
</TableLayout>

预览图如下。


image.png

3.TableLayout中添加以下属性: android:shrinkColumns = "1"设置第二个列为可收缩列。

<TableLayout android:id="@+id/TableLayout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:shrinkColumns="1"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="one" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="two" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="three" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="four" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="five" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="文本XX" />

    </TableRow>
</TableLayout>

预览图如下。

image.png

使用场景可以看这篇大致了解一下
Tablayout使用全解,一篇就够了

https://www.jianshu.com/p/fde38f367019

Tablayout与GridLayout 相比,优点是更灵活,稍微有点类似RelativeLayout和LinearLayout之间的关系。一个可调整性高,一个写起来简单。

现在就剩下六大布局中的最后一个AbsoluteLayout。
由于android中已经将这个api废弃,因此不推荐使用,但是还是简单通过一个xml文件了解一下。

<AbsoluteLayout 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">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="16dp"
        android:layout_y="135dp"
        android:text="邮箱"
        tools:layout_editor_absoluteX="36dp"
        tools:layout_editor_absoluteY="64dp" />

    <EditText
        android:id="@+id/login_email"
        android:layout_width="256dp"
        android:layout_height="wrap_content"
        android:layout_x="64dp"
        android:layout_y="123dp"
        android:inputType="textEmailAddress"
        tools:layout_editor_absoluteX="124dp"
        tools:layout_editor_absoluteY="64dp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="16dp"
        android:layout_y="193dp"
        android:text="密码"
        tools:layout_editor_absoluteX="36dp"
        tools:layout_editor_absoluteY="82dp" />

    <EditText
        android:id="@+id/login_password"
        android:layout_width="256dp"
        android:layout_height="wrap_content"
        android:layout_x="64dp"
        android:layout_y="180dp"
        android:inputType="textPassword"
        tools:layout_editor_absoluteX="124dp"
        tools:layout_editor_absoluteY="87dp" />

    <Button
        android:id="@+id/login_btn"
        android:layout_width="256dp"
        android:layout_height="wrap_content"
        android:layout_x="63dp"
        android:layout_y="247dp"
        android:text="login"
        tools:layout_editor_absoluteX="145dp"
        tools:layout_editor_absoluteY="271dp" />

</AbsoluteLayout>

预览图如下。


image.png

简单看完AbsoluteLayout,下面来看ConstraintLayout 。

ConstraintLayout 
package android.support.constraint;
public class ConstraintLayout extends ViewGroup

ConstraintLayout 与其他布局类不同的是,ConstraintLayout是属于android.support.constraint下的。
现在使用android studio新建一个project默认就会生成ConstraintLayout 的文件。
如下所示。

<android.support.constraint.ConstraintLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

切到design后选中textview后,可进行拖动,从而修改ui。


image.png

通过ConstraintLayout去定义ui,就像在纸上画画一样,而其他的LinearLayout、RelativeLayout等都是通过手动修改xml文件去定义ui。

更多详细部分学习可以看这篇。
哲♂学三幻神带你学习ConstraintLayout(约束布局)

https://www.jianshu.com/p/639fa7377cc0

android六大布局的知识点就到此为止,接下来的问题就是android ui如何适配。
后续看这里。
android UI适配简单记录三
https://www.jianshu.com/p/39dd0adfddc8

参考链接:

Android LinearLayout 线性布局
https://www.twle.cn/l/yufei/android/android-basic-linearlayout.html

布局
https://developer.android.com/guide/topics/ui/declaring-layout?hl=zh-CN
线性布局
https://developer.android.com/guide/topics/ui/layout/linear.html?hl=zh-CN

Android动态创建布局常用方法
https://blog.csdn.net/cpcpcp123/article/details/81747935

Android布局之 FrameLayout
http://wangkuiwu.github.io/2014/03/03/FrameLayout/

Android FrameLayout ( 帧布局 )
https://www.twle.cn/l/yufei/android/android-basic-framelayout.html

Android技巧:学习使用GridLayout
http://toughcoder.net/blog/2015/11/25/android-tricks-introduct-to-gridlayout/

Android GridLayout ( 网格布局 )
https://www.twle.cn/l/yufei/android/android-basic-gridlayout.html

TableLayout ( 表格布局 )
https://www.twle.cn/l/yufei/android/android-basic-tablelayout.html

TableLayout(表格布局)
https://www.runoob.com/w3cnote/android-tutorial-tablelayout.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352