上一节已经做好了文本输入框和发送按钮,那么这节就赋予它们实际的功能:在文本框中任意输入些文字,点击发送按钮,之后便可以跳转另一个界面来显示刚刚输入的文字。
核心:Intent,官方参考链接。
为按钮添加点击函数
在布局xml中为button标签添加一个点击函数,函数名叫sendMessage,添加好后的代码如下:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send"
android:onClick="sendMessage"/>
这样,当用户点击这个按钮后,就会调用sendMessage函数。那么这个函数应该放在哪儿呢?答案是放在.../java/XXX/XXX/XXX/myfirstapp/MainActivity.java中:
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
// Do something in response to button
}
为了能使系统将android:onClick和这里的方法名匹配,这个方法必须具备以下几个特征:
1. public
2. return的类型为void
3. 仅有一个传入变量view(实际将会是点击的那个view)
接下来,我们就可以在这个方法中添加内容,让它读取到文本输入框的内容并传送到下一个界面。
创建一个Intent
Intent中文译为“意图”,是一种为单独的控件之间(例如两个activity)提供运行时绑定的对象。Intent表示的是app“打算做某事”。用Intent可以做很多工作,但是它们最常用的就是去打开另一个界面。Intent and Intent Filters
在sendMessage中添加如下一行函数,Intent就创建好了:
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
}
这里的构造器使用了两个变量:
1. Context,这里用this是因为Activity也是Context的子类;
2. 一个app组件类,系统将会把这个Intent传递给这个类(在这里就是我们要去打开的那个Activity)。
黏贴完上面这行代码你会发现编译出错,因为编译器还不知道DisplayMessageActivity这个类究竟是什么。没关系,先放在那里,我们马上就会创建这个类了。
接下来,我们用findViewById通过ID找到文本输入框,代码如下:
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
}
然后,把文本输入框中的文字赋给我们自定义的字符串变量message,然后用putExtra方法将这个字符串添加到Intent上:
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
}
Intent可以携带键值对这种数据,又名extras。putExtra中的第一个变量就是“键”,第二个变量就是“值”。而这时,编译器又懵逼了,因为它不知道EXTRA_MESSAGE是神马,所以我们要在MainActivity.java类的最开始,定义下这个“键”:
public class MainActivity extends AppCompatActivity {
public final static String EXTRA_MESSAGE = "com.wenhe.myfirstapp.MESSAGE";
//...
}
可以看到,我们把包的名字放在了“键”的定义里,原因是这样可以使我们的“键”独一无二,尤其是在和其他app交互的时候。
到这里,Intent已经创建完成了,之后调用startActivity方法,传入我们创建的Intent,就可以打开新的界面了。最后sendMessage方法代码如下:
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
// Do something in response to button
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
自动导包
由于使用了Intent,所以我们要在代码最开始导入下面这个包:
import android.content.Intent;
亲妈说,在Windows上使用Alt+Enter或者是Mac上使用option+return都可以导入缺少的包。但这太麻烦,每次要手动,让Android Studio自动帮我们完成吧,具体方法如下:
File -> Settings -> Editor -> General -> Auto Import,下面红框中的全部勾选,oh yeah:
创建第二个界面
所有的Activity子类都要实现onCreate这个方法,Activity在这个方法中接收Intent消息,并渲染呈现这个消息。同时,onCreate方法中也必须要使用setContentView()这个方法来定义界面的布局。onCreate()也是Activity初始化各界面组件的地方。
在Android Studio左边的导航栏中右键点击包名,然后选择Blank Activity(Empty Activity创建出来的自带代码更少,也可以选这个):
之后按照下图来填写Activity相关信息和布局文件信息,之后点击Finish,就建好了:
建好这个Activity之后编译应该就不会出错了,其他什么都不修改,直接编译好真机调试,可以看到点击send按钮后可以跳转到新的页面,但是页面并没有显示我们输入的文字。原因是我没还没设置让这个界面接收传递过来的Intent。
如果你点开DisplayMessageActivity.java这个文件的话会发现,有些其他的代码,比方说FloatingActionButton巴拉巴拉,不用管它们,我们目前用不到。
接收Intent
无论用户是通过怎样的方式导航到了某个界面,这个界面都是由Intent启动的。你可以通过getIntent()来获取到启动你这个界面的Intent,同时拿到Intent中所包含的数据。
在DisplayMessageActivity.java的onCreate函数中添加如下代码:
protected void onCreate(Bundle savedInstanceState) {
//...
getSupportActionBar().setDisplayHomeAsUpEnabled(true);// 自带的code,和这节无关
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
}
这样string变量message就拿到了EXTRA_MESSAGE这个“键”所对应的字符串值。
显示消息
既然消息字符串已经拿到了,那接下来就是如何让第二个界面显示这个字符串的问题了。首先,我们先给content_display_message.xml中的RelativeLayout添加一个id便于引用。如果打开activity_display_message.xml你可以看到,它在其中include了这个布局。
< RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:id="@+id/content">
</RelativeLayout>
然后,在DisplayMessageActivity.java的onCreate方法中添加一个TextView文本框,将message的字符串赋给这个文本框:
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
最后,将这个TextView添加到刚刚设置id的那个RelativeLayout当中:
RelativeLayout layout = (RelativeLayout) findViewById(R.id.content);
layout.addView(textView);
完整的DisplayMessageActivity类应该是介个样子滴:
public class DisplayMessageActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.content);
layout.addView(textView);
}
}
之后编译运行,在文本框中输入内容,点击按钮发送,就可以成功跳转到第二个界面并显示刚才的消息了。