【Android】安卓开发中的布局与事件
阅读原文时间:2023年07月08日阅读:3

【Android】安卓开发中的布局与事件

非常简单的百度然后点击下载安装就好了。注意的是,本来我是打算使用评价还不错的Genymotion这个软件来充当虚拟机的,捆版下载VirtualBox先不说,安装了之后还报错无法启动,找了一下午也未解决,最后导致VirtualBox还卸载不了,搞得人头大,所以最终使用了AS自带的虚拟机。

如何配置虚拟机呢,为了不让他下载到C盘,需要改一个环境变量

ANDROID_SDK_HOME
D:\Environment\Android\avd

之后重启AS发现下载的虚拟机文件都在这里面了就说明成功了。

值得注意的是,AS刚开始创建项目的时候gradle构建的非常慢,需要等噢。

配置好了就可以运行Hello world了。

至于如何设置成中文,需要到idea的插件市场下载中文插件,在AS中使用本地安装,虽然部分无法翻译,但是绝大部分都翻译成中文了,还是非常爽滴!

1.xml页面

在AS中可以通过GUI来设置APP,在layout中每一个xml对应一个页面

可以在Design中手动拖拽组件,也可以通过code的方式来写代码构建界面

布局中常用的单位有

  • px(绝对像素,不建议使用)
  • dp(适配单位,建议使用)
  • sp(字体单位)

2.线性布局

2.1 线性布局的使用

其实在Java Swing中也学过,就是一行流下来的那种,在xml中使用LinearLayout标签就可以使用流式布局

下面代码中的match_parent字面意思就是匹配父类的大小

看看加了3个button后的效果

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Button" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Button" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Button" />

</LinearLayout>

2.2 线性布局摆放的方向

在LinearLayout标签中,使用android:orientation=""可以改变布局的摆放方向,有两种——水平和垂直,分别是horizontalhorizontal

可以在design页面的这个按钮中设置

其实改变的就是代码的这一行

2.3 线性布局的权重

权重就是这个元素在一行内容占比,使用layout_weight来表示,每一个元素都可以设置一个权重,我如上的代码就是权重都为1

权重使用的是屏幕的宽度和高度,是成比例的!

假设,现在有3个button,每个权重分别是1,1,2,那么第一个和第二个button占了1/4,第三个占用了2/4也就是1/2。

3.相对布局

3.1 相对于父级控件

使用标签RelativeLayout就可以使用相对布局了。

默认是相对于控件的左边

我们这里使用的是相对于父控件,使用属性layout_centerInParent,这个是在父控件的中间,true和false两个值可以选择

同理,有layout_alignParentRight,相对于父控件的右边,layout_alignParentLeft,相对于父控件的左边,还有一个相对于父控件的下面layout_alignParentBottom

一个简单的例子

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

    <Button
        android:layout_centerInParent="true"
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="相对于父控件的中间" />

    <Button
        android:layout_alignParentRight="true"
        android:id="@+id/button5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="相对于父控件的右上角" />

    <Button
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:id="@+id/button6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="相对于父控件的右下角" />

    <Button
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"
        android:id="@+id/button7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="相对于父控件的左下角" />

    <Button
        android:layout_alignParentLeft="true"
        android:id="@+id/button8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="相对于父控件的左上角" />

</RelativeLayout>

效果如下:

3.2 相对于同级控件

看代码!

使用layout_toLeftOflayout_toRightOflayout_abovelayout_below来相对于某个控件来布局

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

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="中间"
        android:id="@+id/center" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我在中间的左边"
        android:layout_toLeftOf="@+id/center"
        android:layout_centerInParent="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我在中间的顶部"
        android:layout_centerInParent="true"
        android:layout_above="@+id/center" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我在中间的右边"
        android:layout_centerInParent="true"
        android:layout_toRightOf="@+id/center"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我在中间的底部"
        android:layout_below="@+id/center"
        android:layout_centerInParent="true"/>

</RelativeLayout>

效果如下:

4.绝对布局

已经过时的布局方法,使用AbsoluteLayout标签

layout_xlayout_y设置位置

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

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="100dp"
        android:layout_y="100dp"
        android:text="绝对位置" />

</AbsoluteLayout>

5.表格布局

就是表格的样式,使用TableLayout标签

使用TableRow标签来显示一行

例如

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

    <TableRow>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="3"/>

    </TableRow>

    <TableRow>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="4"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="5"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="6"/>

    </TableRow>

    <TableRow>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="7"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="8"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="9"/>

    </TableRow>

</TableLayout>

效果如下:

6.帧布局

使用FrameLayout标签

例如

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

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="按钮"/>

</FrameLayout>

1.由线性布局开始

使用线性布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="C"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="+/-"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="%"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:background="@color/cardview_shadow_start_color"
            android:text="/"
            android:textSize="20sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="1"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="2"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="3"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="X"
            android:background="@color/cardview_shadow_start_color"
            android:textSize="20sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="4"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="5"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="6"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="-"
            android:background="@color/cardview_shadow_start_color"
            android:textSize="20sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="7"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="8"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="9"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="+"
            android:background="@color/cardview_shadow_start_color"
            android:textSize="20sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dp">
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:gravity="center"
            android:text="0"
            android:textSize="20sp" />
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="1"
            android:textSize="20sp" />
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="="
            android:background="@color/cardview_shadow_start_color"
            android:textSize="20sp" />
    </LinearLayout>

</LinearLayout>

效果如下:

2.给按钮加上边框

接着给每个按钮加上边框

在drawable包下创建一个边框样式,使用shape标签

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#5CEAE7E7"/>
    <stroke
        android:width="1dp"
        android:color="#333333"/>

</shape>

同样的再给橙色的一个样式

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e47f26"/>
    <stroke
        android:width="1dp"
        android:color="#333333"/>

</shape>

最终在每个textView中引入android:background="@drawable/shape_rectangle"

最终效果如下:

3.drawable中的选择器

计算器按钮按下去的时候一般会有一个阴影,这个时候我们可以绑定一个点击事件。

在绑定点击事件之前,先建立两个选择器,用来选择点击时候的渲染和未点击时候的渲染。

selector_white_bg.xml白色按钮的选择器

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/shape_rectangle_grey"/>
    <item android:drawable="@drawable/shape_rectangle"/>

</selector>

selector_orange_bg.xml橙色按钮的选择器

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/shape_rectangle_orange_grey"/>
    <item android:drawable="@drawable/shape_rectangle_orange"/>

</selector>

4.绑定点击事件

现在我们给每个textView绑定上上面的两个选择器。

使用android:background="@drawable/selector_white_bg"即可

如何触发选择器的效果呢?有两种方法,个人认为两种方法是不同的风格!

第一种方法我感觉偏向JavaScript风格,第二种方法偏向Java Swing风格

至于为啥是这两种风格,看我解释就完了~

4.1 第一种方法

我就叫他JS风格方法吧。

首先在需要绑定点击事件的组件中,添加一个android:onClick="oneOnClick",这里的oneOnClick是随便写的,可以是任何字符,其实就是绑定了mainActivity中的一个oneOnClick()方法

MainActivity类中的oneOnClick()方法

TextView组件中绑定的onClick方法

如上的两个步骤就可以触发点击事件了

效果如下:

同时我们可以看到控制台上有log输出(点击后方法被执行了)

4.2 第二种方法

如果你熟悉Java Swing的开发,那么对于这种方法肯定不陌生!

简单来说就是在MainActivity类中,让每一个空间成为类中的属性,在初始化的时候成为成员变量,然后给每个组件按上一个点击事件的监听器,监听器中写上点击事件需要执行的代码就好啦!

package top.woodwhale.hello;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private TextView cancel;
    private TextView plusOrMinus;
    private TextView mod;
    private TextView div;
    private TextView zero;
    private TextView one;
    private TextView two;
    private TextView three;
    private TextView four;
    private TextView five;
    private TextView six;
    private TextView seven;
    private TextView eight;
    private TextView nine;
    private TextView point;
    private TextView add;
    private TextView multi;
    private TextView sub;
    private TextView eq;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.caculator);
        this.initView();
        this.initClickEvent();
    }

    // 获取TextView组件
    public void initView() {
        cancel = this.findViewById(R.id.tv_cancel);
        plusOrMinus = this.findViewById(R.id.tv_plus_or_minus);
        mod = this.findViewById(R.id.tv_mod);
        div = this.findViewById(R.id.tv_division);
        zero = this.findViewById(R.id.tv_zero);
        one = this.findViewById(R.id.tv_one);
        two = this.findViewById(R.id.tv_two);
        three = this.findViewById(R.id.tv_three);
        four = this.findViewById(R.id.tv_four);
        five = this.findViewById(R.id.tv_five);
        six = this.findViewById(R.id.tv_six);
        seven = this.findViewById(R.id.tv_seven);
        eight = this.findViewById(R.id.tv_eight);
        nine = this.findViewById(R.id.tv_nine);
        point = this.findViewById(R.id.tv_point);
        add = this.findViewById(R.id.tv_add);
        multi = this.findViewById(R.id.tv_multiplication);
        sub = this.findViewById(R.id.tv_subtraction);
        eq = this.findViewById(R.id.tv_equal);
    }

    // 给每个组件添加一个监听器
    public void initClickEvent() {
        MyListener listener = new MyListener();
        cancel.setOnClickListener(listener);
        plusOrMinus.setOnClickListener(listener);
        mod.setOnClickListener(listener);
        div.setOnClickListener(listener);
        zero.setOnClickListener(listener);
        one.setOnClickListener(listener);
        two.setOnClickListener(listener);
        three.setOnClickListener(listener);
        four.setOnClickListener(listener);
        five.setOnClickListener(listener);
        six.setOnClickListener(listener);
        seven.setOnClickListener(listener);
        eight.setOnClickListener(listener);
        nine.setOnClickListener(listener);
        point.setOnClickListener(listener);
        add.setOnClickListener(listener);
        multi.setOnClickListener(listener);
        sub.setOnClickListener(listener);
        eq.setOnClickListener(listener);
    }
}

class MyListener implements View.OnClickListener {

    @Override
    public void onClick(View view) {
        if (view instanceof TextView) {
            String s = ((TextView) view).getText().toString();
            Log.d("MainActivity","TextView中的text为:"+s);
        }
    }
}

是不是非常的熟悉?这就是Swing中的思想。这样我们不需要在xml中绑定事件,只需要在MainActivity中设置监听器就好啦!

运行效果如下: