Android项目的创建和运行
Q7nl1s admin

主要内容:Android项目创建 + 运行 + 调试

image-20230308143242188

创建Android项目

image-20230308143349137

image-20230308143406492

image-20230308143420613

image-20230308143434971

如果碰到 gradle 下载慢可以采用阿里云镜像来加速:

修改项目根目录下的文件 build.gradle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
buildscript {
repositories {
//google()
//jcenter()
maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/google/'}
maven { url 'https://maven.aliyun.com/repository/jcenter/'}
mavenLocal()
mavenCentral()
}
...
}
allprojects {
repositories {
//google()
//jcenter()
maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/google/'}
maven { url 'https://maven.aliyun.com/repository/jcenter/'}
mavenLocal()
mavenCentral()
}
}

参考:gradle下载慢的解决方案

备注2:如果出现 gradle jdk 版本报错(似乎是 AS 升级导致)

image-20230308143506996

项目创建成功:第一次创建项目等待时间较长

image-20230308143631683

查看 APP 界面布局

image-20230308143703356

运行Android程序

◼ 在 AVD 模拟器上运行程序(AVD 首次启动较慢)
◼ 在真实设备上运行程序(手机需要 USB 数据线连接和开启 USB 调试)

APP运行过程

image-20230308143810571

APP运行结果

image-20230308143835822

在真实设备上运行程序

◼ 连接准备:
◼ 先在手机设置中开启开发者选项:需开启 USB 调试、开启 USB 安装等功能 ==注:不同品牌的手机开启方式不太一样,需要查询一下==
◼ 然后将手机通过 USB 与电脑连接

image-20230308144334302

选择真实设备运行:

image-20230308144407676

Android程序调试

◼ 两种方法:
◼ Debug模式(断点调试)
◼ 日志模式(使用Log.d()将调试信息记录在系统日志中, 配合LogCat查看日志)

程序调试示例

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MainActivity extends AppCompatActivity {
private int a;
public void count() {
a++;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
count();
System.out.println(a);
}
}

Debug模式

image-20230308144526922

image-20230308144603062

Debug 窗口:常用调试工具

image-20230308144634034

日志模式

image-20230308144656913

image-20230308144801396

补充:Logcat 的一些匹配模式

image-20230308144834659

Android编程基础

掌握基础编程:
◼ UI组件和布局
◼ 界面主题Theme
◼ 基于监听的事件处理机制
◼ Toast消息提示框
◼ Snackbar对话框
◼ AlertDialog对话框
◼ 基于回调的事件处理机制
◼ 代码重写封装

UI组件和布局

image-20230308144951516

注:如果不存在约束布局,直接将组件拖入 XML 文件中,则会造成在程序运行时的置顶显示。

UI组件属性设置:

image-20230308145021493

关于 Android 的尺寸单位

◼ 常用:
◼ sp (scaled pixels):常用于指定字体大小,当用户自定义手机字体大小(如小、正常、大、超大等),字体大小会随之改变
◼ dp (density-independent pixels):设备无关像素,这种尺寸单位在不同设备上的物理大小相同,非文字尺寸(如宽度/高度)使用 dp 单位
◼ 其他:
◼ px (pixel):像素,屏幕上显示数据的最基本的点
◼ pt (point):磅,1pt=1/72inch,通常用来作为字体的尺寸单位
◼ inch:英寸,1 英寸约等于 2.54 厘米,主要用来描述手机屏幕大小

关于背景的一些属性
◼ background:是一个可绘制的背景 (可以是一个资源的引用,如图片、可调整大小的 9-patch 位图、XML
状态描述等,或者是颜色如白色)
◼ backgroundTint:是应用到背景上的色彩(只能是颜色),默认会覆盖 background(叠加模式)
◼ backgroundTintMode:设置 backgroundTint 的模式,默认是叠加模式:mulitply

◼ 说明:由于 APP 的主题默认把按钮的 background 设置为 purple_500,所以通过 background 属性修改没有起作用

界面主题Theme

◼ 主题决定了 APP 的展示效果
◼ 可以为整个应用指定主题
◼ 可以为 Activity 单独指定主题
◼ 还可以为各个控件,如 Button、TextView,指定主题

主题定义

(1)界面的主题定义位于:res/values/themes.xml 文件

image-20230308145502850

image-20230308145550909

Primary、Secondary 等基准颜色对照

image-20230308145838045

(2)应用程序的主题在 AndroidManifest.xml 的 theme 属性中引用:

AndroidManifest.xml:应用配置文件(或清单文件)

image-20230308145921742

测试:修改界面主题为桥主题

(1)修改主题的 parent 属性:添加 .Bridge

(2)在桥主题下,可修改按钮的 background 颜色值(试一下)

image-20230308150003771

了解:一些原生 MaterialComponents 主题

image-20230308150025822

尝试添加自己的主题

1
2
3
4
5
6
<style name="btnStyle">
<item name="android:backgroundTint">#03A9F4</item>
<item name="android:textSize">18sp</item>
<item name="android:layout_width">150dp</item>
<item name="android:layout_height">80dp</item>
</style>

将以上代码 copy 到 values/themes 包下的 themes.xml 文件中

image-20230310114137881

再在 activity_main.xml 中指定自己新添的 themes

image-20230310114337006

接着,我们可以看到自定义样式已经被覆盖了

image-20230310114520256

基于监听的事件处理机制

◼ 事件:表示程序和用户之间的交互,例如:单击按钮、在文本框中输入、选中单选按钮等
◼ 事件处理:表示程序对事件的响应
◼ 当事件发生时,系统会自动捕捉这一事件,同时创建事件对象并把它们传给事件监听器,后者调用相应的事件处理程序,以使用户得到相应的回答

事件监听处理机制流程:事件监听机制:由事件源,事件以及事件监听器三类对象组成

image-20230308150211334

事件监听示例:用匿名内部类实现(一次性,不能复用)

◼ 以按钮编程为例:

1
2
3
4
5
6
7
Button btn = (Button) findViewById( R.id.按钮id );	// findViewById():根据id查找组件(推荐加强转)
btn.setOnClickListener( new View.OnClickListener() { // 给按钮添加Click监听器;创建事件监听器:使用匿名内部类实现
@Override
public void onClick(View v) { // 实现事件处理(接口的Click方法)
// 处理代码
}
});

补充:用Lambda表达式实现更简洁
btn.setOnClickListener( v -> {
//处理代码
});

按钮编程示例:

1
2
3
4
5
6
7
8
9
10
11
12
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn1 = (Button) findViewById( R.id.btn_test );
btn1.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView tv = (TextView) findViewById( R.id.msg );
tv.setText("武汉科技大学");
}
});
}

image-20230308150510435

事件监听示例:用内部类实现(可复用)

◼ 以按钮编程为例:

1
2
3
4
5
6
7
8
9
10
// ① 先定义一个内部类,实现View.OnClickListener接口,并重写onClick()方法
class BtnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.按钮id1: …
case R.id.按钮id2: …
}
}
}
1
2
3
4
5
6
// ② 然后给按钮设置监听器 (直接new一个内部类对象作为参数)
Button btn1 = (Button) findViewById(R.id.按钮id1);
btn1.setOnClickListener( new BtnClickListener() );

Button btn2 = (Button) findViewById(R.id.按钮id2);
btn2.setOnClickListener( new BtnClickListener() );

按钮编程示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MainActivity extends AppCompatActivity {
//定义内部类
class BtnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_test:
TextView tv = (TextView) findViewById(R.id.msg);
tv.setText("武汉科技大学");
break;
case R.id.btn_exit:
finish(); // 结束当前activity
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn1 = (Button) findViewById(R.id.btn_test);
btn1.setOnClickListener( new BtnClickListener() );
Button btn2 = (Button) findViewById(R.id.btn_exit);
btn2.setOnClickListener( new BtnClickListener() );
}
}

Toast消息提示框

◼ Toast:是一种简易的消息提示框,用于在应用程序上浮动显示少量信息,以告知用户任务状态或操作结果,例如:发送成功,加载中,删除成功等。
◼ 主要特点:
◼ Toast 会显示在屏幕所有层的最上方
◼ Toast 会根据用户设置的显示时间后自动消失
◼ 同一时间只显示一条 Toast
◼ Toast 不会获得焦点(无法被点击),不影响用户输入

image-20230308150908228

Toast创建方法

◼ 链式写法:

1
Toast.makeText( context, text, duration ).show(); 

image-20230308151008984

  • context:上下文参数->当前 Activity.this 或 getApplicationContext()

  • text:显示的信息

  • duration:显示时长

    ◼ Toast.LENGTH_SHORT (大约1秒)
    ◼ Toast.LENGTH_LONG (大约3秒)
    ◼ 或自己指定的毫秒数

  • show:显示 toast

Toast编程示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn1 = (Button) findViewById( R.id.btn_test );
btn1.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView tv = (TextView) findViewById( R.id.msg );
tv.setText("武汉科技大学");
Toast.makeText( MainActivity.this, "设置完成", Toast.LENGTH_SHORT ).show();
// MainActivity 是当前 Activity 名
// 消息内容:"设置完成"
// 显示时长:Toast.LENGTH_SHORT
// show():不能忘记!!!
}
});
}
image-20230308151512789

Snackbar对话框

◼ Snackbar:能为用户提供快速弹出消息,且具有交互性
◼ 主要特点:
◼ 与 Toast 类似,都是为了给用户显示消息
◼ Snackbar是在屏幕底部显示消息(所有其他元素的上方)
◼ 可以与用户交互操作
◼ 同一时间只显示一条 Snackbar

Snackbar用法1:无交互情况

1
Snackbar.make( view, text, duration ).show(); 
  • view:View 组件->常用 findViewById( R.id.界面布局id ) 也可以用界面布局中其他 View 组件

  • text:显示的信息

  • duration:显示时长

    ◼ Snackbar.LENGTH_SHORT
    ◼ Snackbar.LENGTH_LONG
    ◼ Snackbar.LENGTH_INDEFINIT(永不消失,除非手动调用 dismiss() 方法)

  • show:显示Snackbar

Snackbar用法2:有交互情况

1
2
3
4
5
6
7
8
Snackbar.make( view, text, duration )
.setAction("按钮文字", new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击按钮之后的操作
}
})
.show();

image-20230308151912740

Snackbar用法示例

1
2
3
4
5
6
7
8
9
10
Snackbar.make( findViewById( R.id.contraintLayout ), "确定退出吗?", Snackbar.LENGTH_SHORT)
.setAction("确定", new View.OnClickListener() {
@Override
public void onClick(View v) {
finish(); //结束当前Activity
}
})
.setActionTextColor(Color.RED) // 设置按钮的文字颜色
.setBackgroundTint(Color.BLUE) // 设置背景色
.show();

R.id.contraintLayout:给布局设置的 id 值

image-20230308152042252

AlertDialog对话框

◼ AlertDialog:可以在当前的界面上显示一个对话框
◼ 这个对话框是 置顶于所有界面元素之上的,能够屏蔽掉其他控件的交互能力
◼ AlertDialog 一般是用于提示一些重要的内容或者警告信息

image-20230308152122391

AlertDialog创建过程

  1. 创建构造器 AlertDialog.Builder 对象
  2. 构造器对象调用 setTitlesetMessagesetIcon 等方法构造对话框的标题、信息和图标等内容
  3. 根据需要调用 setPositivesetNegative 方法设置确定、取消按钮
  4. 调用构造器对象的 show 方法显示对话框

AlertDialog编程框架:链式写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 先创建构造对象 (AlertDialog.Builder)
new AlertDialog.Builder( 当前Activity.this ) // 上下文参数
// 设置图标
.setIcon( R.drawable.图片资源id )
// 设置标题
.setTitle("提示")
// 设置信息
.setMessage("确定退出吗?")
// 设置确定按钮
.setPositiveButton("确定", new DialogInterface.OnClickListener() { // 添加按钮监听器
@Override
public void onClick(DialogInterface dialog, int which) {
// 处理代码
}
})
// 设置取消按钮
.setNegativeButton("取消", null) // 设置为 null 不添加监听(默认是关闭对话框)
// 显示
.show();

◼ setPositiveButton 方法:设置”确定”按钮功能
◼ setNegativeButton 方法:设置”取消”按钮功能

image-20230308152724205

图片资源的导入方法

image-20230308152748388

AlertDialog编程示例

下面的代码放在 onCreate 方法中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Button btn2 = (Button) findViewById( R.id.btn_exit );
btn2.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder( MainActivity.this )
.setIcon( R.drawable.alert ) // R.drawable.alert 是一个图片资源id
.setTitle("提示")
.setMessage("确定退出吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish(); // 结束当前activity
}
})
.setNegativeButton("取消", null)
.setCancelable(false) // 点击对话框以外的区域不让对话框消失
.show();
}
});

image-20230308153005986

高级AlertDialog

image-20230308153030764

(1) 带列表项的对话框:setItems 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Button btn3 = (Button) findViewById(R.id.list_0);
btn3.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
final String[] items = new String[]{"选项1", "选项2", "选项3","选项4"};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setIcon(android.R.drawable.ic_dialog_info); // 图片ID
builder.setTitle("请选择选项:");
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "你选择了" + items[which], Toast.LENGTH_SHORT).show();
}
});
builder.show();
}
});

image-20230308153356582

(2) 带单选列表项的对话框:setSingleChoiceItems 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Button btn3 = (Button) findViewById(R.id.list_0);
btn3.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
final String[] items = new String[]{"Java", "C", "C++", "Python", "C#"};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setTitle("选择你最擅长的开发语言:");
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() { // 初始选中项序号,-1表示不选中任何项
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "你选择了" + items[which], Toast.LENGTH_SHORT).show();
}
});
builder.setPositiveButton("确定", null);
builder.show();
}
});

image-20230308153558304

(3) 带多选列表项的对话框:setMultiChoiceItems 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Button btn3 = (Button) findViewById(R.id.list_0);
btn3.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean[] checkedItems = new boolean[5]; //选中项状态
final String[] items = new String[]{"Java", "C", "C++", "Python", "C#"};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setTitle("选择你喜欢的开发语言:");
builder.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
checkedItems[which] = isChecked;
}
});
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String result = "";
for (int i = 0; i < checkedItems.length; i++) {
if (checkedItems[i]) {
result += items[i] + ","; //获得选中项内容
}
}
if (!"".equals(result)) {
result = result.substring(0, result.length() - 1); //不为空串时去掉最后的","
Toast.makeText(MainActivity.this, "您选择了" + result , Toast.LENGTH_LONG).show();
}
}
});
builder.show();
}
});

image-20230308153841132

(4) 自定义布局的对话框:setView 方法

image-20230313164031645

自定义的布局:login.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">
<TextView
android:id="@+id/tip2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginTop="30dp"
android:text="密 码"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tip1" />
<TextView
android:id="@+id/tip1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginTop="30dp"
android:text="用户名"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:ems="10"
android:inputType="textPersonName"
app:layout_constraintBaseline_toBaselineOf="@+id/tip1"
app:layout_constraintStart_toEndOf="@+id/tip1" />
<EditText
android:id="@+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:ems="10"
android:inputType="textPassword"
app:layout_constraintBaseline_toBaselineOf="@+id/tip2"
app:layout_constraintStart_toEndOf="@+id/tip2" />
</androidx.constraintlayout.widget.ConstraintLayout>

在 MainActivity.java 中添加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setTitle("登录");
//加载自定义布局
LayoutInflater factory = LayoutInflater.from(MainActivity.this);
final View dialogView = factory.inflate( R.layout.login, null );
builder.setView(dialogView);
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
EditText un = (EditText) dialogView.findViewById(R.id.username);
EditText pwd = (EditText) dialogView.findViewById(R.id.password);
Toast.makeText(getApplicationContext(), "姓名 :" + un.getText().toString()+ "\n密码:"+ pwd.getText().toString(),Toast.LENGTH_SHORT).show();
}
});
builder.show();

程序登录验证页面

Snipaste_2023-03-13_16-45-21

进入后显示刚才的输入

Snipaste_2023-03-13_16-46-01

基于回调的事件监听机制

回调是一种双向的调用模式

◼ 回调(方法回调):是将功能定义与功能分开的一种手段,是一种解耦合的设计思想
◼ Java回调是通过接口来实现的,系统通过在不同的状态下”回调”实现类,从而达到接口和实现的分离
◼ 如何理解回调:
◼ 比如:你放学回家,问老妈饭做好没,你妈说还没有;然后你跟她说:老妈,我先在外面玩一下,饭好了就叫我哈!
◼ 分析:你和老妈约定了一个接口,你通过这个接口叫老妈做饭,当饭做好时,你老妈又通过这个接口来反馈你:”饭做好了” (回调方法)

image-20230313164727601

回调事件监听示例:以Activity的onKeyDown监听为例

◼ onKeyDown 方法:在 Activity ==强调== 中监听手机屏幕上的按键
◼ 比如:监听返回键,提示退出

onKeyDown 监听基本框架:

1
2
3
4
5
6
7
8
9
10
@Override
// onKeyDown 也是类成员方法(与 onCreate 并列关系)
// (1) keyCode参数:被按下键的键盘码
// (2) event参数:按键事件
public boolean onKeyDown(int keyCode, KeyEvent event) {
if( keyCode == event.某个键盘码 ) { // 例如返回键键盘码:KEYCODE_BACK
//监听处理
}
return super.onKeyDown(keyCode, event);
}

关于返回值:
◼ 当返回true时,表示已经完整地处理了这个事件,并不希望其他的回调方法再次进行处理
◼ 当返回false时,表示并没有完全处理完该事件,更希望其他回调方法继续对其进行处理

onKeyDown示例1:监听返回键(支持手势),AlertDialog提示退出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if( keyCode == event.KEYCODE_BACK ) {
new AlertDialog.Builder(MainActivity.this)
.setIcon(R.drawable.alert)
.setTitle("提示")
.setMessage("确定退出吗?")
.setPositiveButton("确定",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton("取消", null)
.show();
}
return true;
}

onKeyDown示例2:2秒之内按再次按返回键退出,否则进行提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private long clickTime = 0L; //记录当前时间
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if( keyCode == event.KEYCODE_BACK ) {
if (System.currentTimeMillis() - clickTime > 2000) {
Toast.makeText(this, "再按一次退出!", Toast.LENGTH_SHORT).show();
clickTime = System.currentTimeMillis();
} else {
finish();
}
return true; //加一个返回
}
return super.onKeyDown(keyCode, event);
}

代码重新封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class MainActivity extends AppCompatActivity {
// 用类成员形式定义变量
private Button btn1;
private Button btn2;
private TextView tv;
private View.OnClickListener listener = new View.OnClickListener() { // 匿名内部类实现事件监听的另一种写法
@Override
public void onClick(View view) {
switch ( view.getId() ) {
case R.id.btn_test:
test(); // 自定义test()方法
break;
case R.id.btn_exit:
alert(); // 自定义alert()方法
break;
}
}
};

public void init() { // 自定义初始化方法(在界面布局加载之后调用)
btn1 = (Button) findViewById(R.id.btn_test);
btn2 = (Button) findViewById(R.id.btn_exit);
tv = (TextView) findViewById(R.id.msg);

// 将监听器绑定给按钮组件:多个按钮注册到同一个事件监听器
btn1.setOnClickListener( listener );
btn2.setOnClickListener( listener );
}

public void test() { // 自定义test()方法
tv.setText("武汉科技大学");
Toast.makeText(MainActivity.this, "设置完成", Toast.LENGTH_SHORT).show();
}

public void alert() { // 自定义alert()方法
new AlertDialog.Builder(MainActivity.this)
.setIcon(R.drawable.alert)
.setTitle("提示")
.setMessage("确定退出吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton("取消", null)
.show();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init(); // 调用init()初始化方法(先加载界面布局)
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == event.KEYCODE_BACK) {
alert(); // 调用alert()方法
}
return true;
}
}
}
 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
Unique Visitor Page View