Android 学习笔记三:Activity

来源:互联网 发布:算法与并行计算 编辑:程序博客网 时间:2024/05/21 11:17

继续上一章,我们看了一下基本的目录结构。那么现在我们要把那个简单的Helloworld界面改的复杂一点了。

增加输入框和按钮

现在把helloworl改成一个登录界面。需要增加两个输入框和一个按钮:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"    android:orientation="vertical">    <TextView android:text="@string/title"        android:layout_width="match_parent"        android:layout_height="wrap_content"        />    <EditText        android:id="@+id/username"        style="@style/EditTextStyle"        android:layout_height="wrap_content"        android:layout_width="match_parent"        android:hint="@string/username_hint"        android:imeActionId="@+id/username"        android:imeOptions="actionUnspecified"        android:inputType="text"/>    <EditText        android:id="@+id/password"        style="@style/EditTextStyle"        android:layout_height="wrap_content"        android:layout_width="match_parent"        android:hint="@string/password_hint"        android:imeActionId="@+id/password"        android:imeOptions="actionUnspecified"        android:inputType="textPassword"/>    <Button        android:id="@+id/button_login"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="@string/button_login"        /></LinearLayout>

代码如上。我们首选要把 RelativeLayout 改成一个 LinearLayout,并且把布局改成垂直的,这样就可以一行一个来布局了。然后增加两个输入框和一个按钮。

之前说过 @xxx 的语法是引用 res 中的资源,不过这里有一个特殊的地方 @+id/username ,其实在res中并没有定义一个username的字段。这里的加号表示不是引用 而是直接创建一个id。另外的一些属性看一下名字就知道什么意思了,不然就去官网上查。相应的, strings.xml 文件也要增加一些字段,这里就不贴出来了。

改完之后运行,会发现现在已经有一个很粗糙的登录界面了,只不过点击了没有任何反应。

增加事件监听

现在我们希望在点击登录按钮之后能有一些反应,比如弹出一个对话框什么的。需要做的就是给Button绑定一个click事件。

protected void initialize() {    Button loginButton = (Button) findViewById(R.id.button_login);    final Editable username = ((EditText)findViewById(R.id.username)).getText();    loginButton.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Toast.makeText(MainActivity.this, "您的用户名是:" + username, Toast.LENGTH_LONG).show();        }    });}

参考上面的代码,几个重点:

  1. 通过 findViewById(R.id.button_login) 可以找到你需要的控件,其中的id就是通过 @+id/xxx 定义的,不过这个函数总是返回一个View,所以你需要自己转换一下
  2. 通过 loginButton.setOnClickListener 来绑定一个点击事件,并且在其中调用toast弹出一个消息。

创建并启动一个新的Activity

到目前为止我们都在一个Activity中折腾,下面我们创建一个新的Activity:

创建一个Activity需要创建两个文件,一个是Java类,一个是对应的xml文件。不过Android Studio可以自动帮我们做这件事,选中java包,右键选择 new -> activity -> blank activity 然后输入一个名字即可。点击完成之后会自动两个文件,一个 ProfileActivy.java 和一个 activity_profile.xml,并且会自动在 AndroidManifest.xml 中注册这个活动,如果你没有用IDE或者是想尝试下手动创建,那么你需要自己做这三件事。

然后我们希望当用户点击确定按钮的时候,我们打开这个新的activity并且把用户输入的内容传过去。

首先我们需要改一下 MainActivity.java 文件:

protected void initialize() {    Button loginButton = (Button) findViewById(R.id.button_login);    loginButton.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Intent intent = new Intent(MainActivity.this, ProfileActivity.class);            final String username = ((EditText)findViewById(R.id.username)).getText().toString();            intent.putExtra(PROFILE_MESSAGE, username);            startActivity(intent);        }    });}

我们这里用到一个新的类叫 Intent ,这个Intent就是用来打开另外一个 Activity 用的(当然还有别的作用,不过主要是这个)。 它的两个参数分别是当前的 Context 和 需要打开的 Activity。

intent 有一个 putExtra 方法,可以以键值对的方式向下一个 activity 传递数据,这里我们就把用户输入的用户名传过去。

再打开 ProfileActivity.java 文件,我们需要接收intent传过来的参数,这样写:

 @Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_profile);    Intent intent = getIntent();    String message = intent.getStringExtra(MainActivity.PROFILE_MESSAGE);    TextView profileText  = (TextView) findViewById(R.id.profile_text);    profileText.setText(message);}

通过 getIntent() 方法我们就可以取到打开当前activity的intent,然后用 getStringExtra 来取传过来的参数。最后设置到 textview 中去即可。

隐式Intent

上面 new Intent(MainActivity.this, ProfileActivity.class) 是通过显示的指定了class来创建一个intent。实际上这样会导致代码耦合,因为指定的class是一个实现类。我们更希望只要声明自己只需要指定一个名字,而不用关心是哪一个具体的类实现的,比如我们只要指定是 com.lihongxun.Profile 就行了,不想关心到底是哪个类实现的,而对应的activity也声明自己提供的是 com.lihongxun.Profile 就行了。

那么我们需要做的就是先在 AndroidManifest.xml 中的声明中指定一个名字:

    <activity        android:name=".ProfileActivity"        android:label="@string/title_activity_profile" >        <intent-filter>            <action android:name="com.lihongxun.Profile" />            <category android:name="android.intent.category.DEFAULT" />        </intent-filter>

然后在java中通过名字调用即可:

 Intent intent = new Intent("com.lihongxun.Profile");

可能看到这里还是觉得这种隐式调用很鸡肋,明明有class,没必要在申明一个名字。
其实这样做的最重要一点在于,你可以调用其他的应用的功能。只要知道一个名字就行了,因为不可能拿到别人的实现类。比如你可以调用支付宝的支付接口。

向上一个活动返回数据

上面说到了通过 intent 可以向打开的下一个活动传递数据,那么同样的,也可以在当前活动关闭的时候向上一个活动返回数据。

向上一个活动返回数据,只需要做三处修改

一,在 MainActivity 中把 startActivity(intent); 改成 startActivityForResult(intent); 也就是声明要开始一个有返回数据的活动
二,在 MainActivity 中注册一个事件,用来接受返回的数据:

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    switch (requestCode) {        case 1:            if (resultCode == RESULT_OK) {                String result = data.getStringExtra("result");                Toast.makeText(this, result, Toast.LENGTH_LONG).show();            }            break;        default:    }}

三,在 ProfileActivity 中设置返回值,通过一个intent来设置返回值,代码如下:

@Overridepublic void onBackPressed() {     //当点击回退按钮的时候触发    //向上一个活动返回数据    Intent intent = new Intent();    intent.putExtra("result", "I am the result");    setResult(RESULT_OK, intent);    finish();}
0 0
原创粉丝点击