安卓基础控件(EditText、Button)以及布局(约束布局)的介绍
目录
一、EditText
EditText是允许用户输入和编辑内容的文本框,并且可以在程序中对这些内容进行处理。EditText的应用场景非常普遍,在网页搜索💻、发微信聊天📱、登陆页面输入账号等操作中必然要用到EditText。例如:
代码展示
那么就让我们看看如何在界面上加入EditText。
第一步:修改activity_main.xml 中的代码,可以根据自己的需要给EditText定义一个id,再修改控件的宽度和高度。
<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"
tools:context=".MainActivity">
<EditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
第二步:可以在输入框中加入提示性的文字,当用户输入内容后提示性的文字就会消失。在EditText的代码里面加入hint属性。
<EditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Type something here"
/>
不过当我们输入的内容不断增多,EditText会被不断拉长,界面就会变难看。我们可以使用maxLines属性来解决这个问题。
第三步:添加android:maxLines属性。
<EditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Type something here"
android:maxLines="2"
/>
这样就指定了EditText的最大行数为两行,超过两行时,文本就会向上滚动,而输入框不会继续拉伸。
二、Button
Button是用户可以点击的按钮,也是一个常见的控件。
比如说这里就有很多个按钮,每个按钮样式都不同。
(上网偷图…)
代码展示
Button的属性其实和TextView差不多,有id,有长宽,可以在上面写文字,即 text属性。
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"
android:textAllCaps="false"
>
</Button>
注意:Button中所有英文字母会自动进行大写转换,如果想转小写需要把 android:textAllCaps属性设置为false。
三、应用例子
接下来,让我们结合Button的知识编写一个订购咖啡的界面☕。
当按“+”和“-”按钮,订购的咖啡杯数变化,与此同时价格“Price”的数字也要跟随着重新进行计算。
我们先学习制作和实现里面的一部分界面和功能。
要制造的页面如图:
(1)布局代码展示
在activity_main.xml 中加入以下代码。
<?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"
tools:context=".MainActivity"
android:orientation="vertical"
android:padding="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="quantity"
android:layout_marginBottom="16dp"
android:textAllCaps="true">
</TextView>
<Button
android:layout_width="48dp"
android:layout_height="48dp"
android:text="+"
android:layout_marginBottom="16dp"></Button>
<TextView
android:id="@+id/quantity_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="0"
android:layout_marginBottom="16dp"
android:textColor="@android:color/black"></TextView>
<Button
android:layout_width="48dp"
android:layout_height="48dp"
android:text="-"
android:layout_marginBottom="16dp"></Button>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="price"
android:textAllCaps="true"></TextView>
<TextView
android:id="@+id/price_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$0"
android:textSize="16sp"
android:textColor="@android:color/black"></TextView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="order"
android:textAllCaps="false"
></Button>
</LinearLayout>
这个界面中有4个TextView,三个Button。
android:orientation=“vertical” 表示控件都是垂直方向线性排列。
因为多个控件贴得太紧不好看,我们可以调整属性:
layout_marginTop 表示所在控件距上部最近控件的最小值。我们可以给每个视图之间留16dp空白,可以设置内边距或者外边距参数来实现。
layout_marginBottom 可以指定该属性所在控件距下部最近控件的最小值。
android:textAllCaps 这个属性设置为true时,文字变成大写,比如这里的 “QUANITY”是全大写。当我们想要改小写的时候,不用改文本,只用把属性删掉就好。
android:id="@+id/quantity_text_view",android:id="@+id/price_text_view" 我们在这里给按钮加上id,是为了方便我们之后给按钮添加对应的功能。(现在的按钮只是个界面,点击了以后没有反应的)
(2)方法
接下来我们希望给按钮添加功能,所以要学习写方法。
我们先来学习一下java方法的概念。(~ ̄▽ ̄)~
方法: 是用来解决一类问题的代码的有序组合,是一个功能模块。
定义方法:
方法的定义由方法名称、参数、返回值类型以及方法体组成
定义方法的语法如下:
访问修饰符 返回值类型 方法名(参数列表){
//方法体
}
1、访问修饰符:方法允许被访问的权限范围,可以是public ,protected ,private,甚至可以省略。其中public表示可以被其他任何代码调用,其他几种修饰符先不详解,可自行百度。
2、返回值类型:方法的返回值的类型,如果方法不返回任何值,则返回值类型指定为void;如果方法具有返回值,则需要指定返回值类型,并且在方法体中使用return语句返回值。
3、方法名:定义的方法的名字,必须使用合法标识符,
4、参数列表,传递给方法的参数列表,参数可以有多个,多个参数之间以逗号隔开,每个参数由参数类型和参数名组成,以空格隔开。
代码例子
1. 无参无返回值方法
public void print(){ //void 表示无返回值,print是方法名
System.out.print("Hello world"); //在控制台输出Hello world
}
2. 无参带返回值方法:由于方法执行后会返回一个结果,因此在调用带返回值的方法时一般都会接收其返回值并进行处理
public int getSum(){ //int表示返回一个整数
int a = 5;
int b = 6;
int sum = a+b;
return sum; //使用return返回值,返回11
}
int a = getSum(); //由上面代码中方法的getSum()返回11,则a=11
3. 带参无返回值方法:调用带参方法与调用无参方法的语法类似,但在调用的时候必须传入实际的参数值
public void show(String name){ //参数name是一个字符串类型
System.out.print("Hello!"+name);
}
show("Quanta安卓"); //输出Hello!Quanta安卓
4. 带参带返回值方法:与上面类似。
(3)功能实现
接下来,我们进入MainActivity.java,添加以下代码。
(注意:要将代码加到public class MainActivity extends AppCompatActivity {}的里面,onCreate方法的外面)
第一步
我们要实现的功能是:点击order后,QUANTITY数量变为1。
/**
*点击order时会执行的方法
*/
public void submitOrder(View view){
display(1);
}
/**
*显示出数量
*/
private void display(int number){
TextView quantityTextView = (TextView)findViewById(R.id.quantity_text_view);
quantityTextView.setText(""+number);
}
看不懂里面的代码?没事的,暂时不用管它,先直接复制吧,以后会深入学习的,之后学会了就可以自己写出来的~ ( •̀ ω •́ )✧
然后我们回到activity_main, 在order的那个Button上面加一个属性:android:onClick=“submitOrder”
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="order"
android:textAllCaps="false"
android:onClick="submitOrder"
></Button>
这时候点击order,会发现quantity那里数字由0变成了1。因为Button添加一个额外的属性:Android:onClick=submitOrder【属性的值是你希望为响应点击事件而调用的方法的名称】,点击的时候就会执行被命名为submitOrder的方法,因为这个方法的作用是把id为quantity_text_view的TextView的text显示为括号里的值,所以就变成了quantity就变成了1,同理如果改成2就会变成2。当然括号内除了能写数字,还能写数学表达式,如22,183+5等。
第二步
接下来要实现:点击显示数量和价钱。
我们把这段代码粘贴到粘贴到 public class MainActivity extends AppCompatActivity {}里面,onCreate方法的外面。
/**
* 在屏幕中显示出价格
*/
private void displayPrice(int number) {
TextView priceTextView = (TextView) findViewById(R.id.price_text_view);
priceTextView.setText(NumberFormat.getCurrencyInstance().format(number));
}
为了显示价格,需要在submitOrder方法中调用displayPrice方法,我们假设是一杯五块钱(当然数量和价格可以由你们自己自行设定),所以参数写成1*15。
public void submitOrder(View view){
display(1);
displayPrice(1*15);
}
现在运行一下,点击order看看结果吧。
(4)变量
我们刚刚显示出来的都是固定的数值,现在我们来尝试使用按钮来改变数量吧~
(下面会涉及到变量的内容,小册子📔第三章出现过的,不记得的回去再看一下变量的命名和变量的定义)
第一步
尝试用变量表示咖啡数量
把submitOrder方法改成
public void submitOrder(View view){
int numberOfCoffee = 2; //设置一个变量来表示咖啡数量,并且初始化为2。
display(numberOfCoffee);
displayPrice(numberOfCoffee*5);
}
上面定义了一个局部变量numberOfCoffee,然后对它进行初始化,值为2。
运行之后是这样的
第二步
做一个数量选择器,点击 “+” ,数量就加一,点击 “-”,数量就减一,然后点order修改价格。
在MainActivity里面添加以下两个方法:
public void decrement(View view){
int quantity = 0; //初始化quantity的值为0
quantity =quantity - 1 ;
display(quantity);
}
public void increment(View view){
int quantity = 0;
quantity =quantity + 1 ;
display(quantity);
}
在increment方法里,先初始化一个数量的变量quantity为0,然后让quantity+1后再把新的值1赋值到quantity这个变量中,最后把新的quantity的值作为参数传给display方法。 decrement方法同理。
第三步
在对应的button里面加上onClick 的属性。
<Button
android:layout_width="48dp"
android:layout_height="48dp"
android:text="+"
android:layout_marginBottom="16dp"
android:onClick="increment"></Button>
<Button
android:layout_width="48dp"
android:layout_height="48dp"
android:text="-"
android:layout_marginBottom="16dp"
android:onClick="decrement"></Button>
但我们会发现这样的方法功能不完善,我们一直点加号却一直停留在1,这是因为这两个方法一直创建新的quantity变量,并且初始值为0。那么怎么修改呢?这里就涉及到了变量作用域的概念。
(5)变量作用域(补充知识点)
1.局部变量:定义在函数内部的变量,它的作用域仅限于函数内部, 离开该函数后就是无效的,再使用就会报错。
2.全局变量:在所有函数外部定义的变量,它的作用域默认是整个程序,也就是所有的源文件。
在这里学习的咖啡点单的应用例子里面,我们在increment方法中声明过一个局部变量 quantity,也在decrement中声明过,之所以我们能声明一个同名变量两次是因为它们在不同的变量作用域。
如果是在一个方法里定义了一个变量,那这个变量只能在这个方法中使用,当方法执行完毕,这些变量就会被销毁。
这是代码中increment方法和decrement方法中的作用域:
因此我们 需要一个全局变量,全局变量可以被应用中的任意一段代码(方法)调用,当一个方法执行完毕之后,不会被销毁。在MainActivity的起始大括号和结束大括号内声明,在MainActivity中就可以调用quantity变量了,把quantity作为全局变量就能存储咖啡的数量了。调用增加或者减少的方法,不会销毁这个值。这个时候quantity的作用域如图:
代码展示
修改之后的代码如下:
int quantity = 0;
public void increment(View view){
quantity =quantity + 1;
display(quantity);
}
public void decrement(View view){
quantity =quantity - 1 ;
display(quantity);
}
public void submitOrder(View view){
display(quantity);
displayPrice(quantity *5);
}
运行之后,可以点击加减选择数量,点击order,就能显示出价钱,一个简单的咖啡点单APP就好了!这其中还有很多可以改进的地方,可以以后慢慢改进~🤪
四、约束布局ConstraintLayout
1.概念
约束布局ConstraintLayout 是一个ViewGroup,它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件。从 Android Studio 2.3 起,官方的模板默认使用 ConstraintLayout。
官方文档
2.怎么使用约束布局?
添加依赖:(一般默认就有)
在app/build.gradle文件的dependencies的括号里面添加依赖。如下:
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
下面是一些相对定位的常用属性:
layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
layout_constraintBaseline_toBaselineOf
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
属性详情
用这张图片总结以下以上属性:
相对定位例子:
如果想要想这样将 TextView1 居中摆放,TextView2 放在 TextView1 的右下,TextView3 在 TextView2的左下,布局文件要这样写:
<!--居中摆放-->
<TextView
android:id="@+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="textView1">
</TextView>
<!--摆放在textview1的右下方-->
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="textview2"
app:layout_constraintTop_toBottomOf="@id/textview1"
app:layout_constraintLeft_toRightOf="@+id/textview1"/>
<!--摆放在textview2的左下方-->
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/textView2"
app:layout_constraintRight_toLeftOf="@id/textView2"
android:text="textview3"/>
ConstraintLayout还提供了另外一种偏移的属性:
layout_constraintHorizontal_bias 水平偏移
layout_constraintVertical_bias 垂直偏移
比如说:刚才输入的TextView1是居中摆放的,现在我们加入layout_constraintHorizontal_bias这个属性:(赋值可以取0~1的数字)
<TextView
android:id="@+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.3"
android:text="textView1">
</TextView>
效果就是这样的:
绝对坐标
之前看到有一些小朋友写作业时使用下面两个属性属性:
app:layout_editor_absoluteX 表示此控件在布局中X轴的绝对坐标点
app:layout_editor_absoluteY 表示此控件在布局中Y轴的绝对坐标点
然后就出现报红的情况了
这是因为明明使用的是约束布局但是没有加约束导致的。这个时候要检查一下ConstraintLayout中的约束条件是否完整,所谓的完整就是水平和垂直的约束都要有。
将代码改成这样就不会报错:
或者是点击这个按钮(让系统帮你自动加上水平和垂直的属性)
边距
ConstraintLayout的边距常用属性如下:
android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
这个其实和RelativeLayout 看起来没什么差别,但是在ConstraintLayout 里面要先约束该控件在ConstraintLayout里的位置。这里还是和上面说的一样,要检查一下ConstraintLayout中的约束条件是否完整。
可以这样写:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="hello world"/>
</android.support.constraint.ConstraintLayout>
也可以这样:
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="hello world"/>
链
如果两个或以上控件通过下图的方式约束在一起,就可以认为是他们是一条链(图为横向的链,纵向同理)。
代码展示
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文本框1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/TextView2"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文本框2"
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintRight_toLeftOf="@+id/TextView3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/TextView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文本框3"
app:layout_constraintLeft_toRightOf="@+id/TextView2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
(这里可以加入app:layout_constraintHorizontal_weight的属性调整三个控件的占比大小,可以自己尝试,这里不展示了)
可以在链头加入layout_constraintHorizontal_chainStyle来改变整条链的样式。(所谓链头,就是水平链中最左侧的控件以及垂直链中最顶部的控件)chains提供了3种样式,如下:
应用
一般什么时候会用到约束布局呢?
1.新闻头条里面出现多个图片并列,比如:
2.头像和昵称的位置摆放:
这里举了两个例子,其实还有很多可以使用约束布局的情况,大家可以自己挖掘一下~
以上就是约束布局的一些基础知识,如果想学习更多用法可以百度一下~