【Android】安卓中的布局与事件
Android Layout and Event...
【Android】安卓中的布局与事件
1、Android Studio下载配置
非常简单的百度然后点击下载安装就好了。注意的是,本来我是打算使用评价还不错的Genymotion这个软件来充当虚拟机的,捆版下载VirtualBox先不说,安装了之后还报错无法启动,找了一下午也未解决,最后导致VirtualBox还卸载不了,搞得人头大,所以最终使用了AS自带的虚拟机。
如何配置虚拟机呢,为了不让他下载到C盘,需要改一个环境变量
ANDROID_SDK_HOME
D:\Environment\Android\avd
之后重启AS发现下载的虚拟机文件都在这里面了就说明成功了。
值得注意的是,AS刚开始创建项目的时候gradle构建的非常慢,需要等噢。
配置好了就可以运行Hello world了。
至于如何设置成中文,需要到idea的插件市场下载中文插件,在AS中使用本地安装,虽然部分无法翻译,但是绝大部分都翻译成中文了,还是非常爽滴!
2、布局
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=""
可以改变布局的摆放方向,有两种——水平和垂直,分别是horizontal
和horizontal
可以在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_toLeftOf
和layout_toRightOf
和layout_above
和layout_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_x
和layout_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>
3、设计一个计算器布局
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中设置监听器就好啦!
运行效果如下: