四大组件之Activity


Activity

Activity的中文意思是活动。在Android中,Activity代表手机屏幕的一屏,或是平板电脑中的一个窗口。它是Android应用的重要组成单元之一,提供了和用户交互的可视化界面。在一个Activity中,可以添加很多组件,这些组件负责具体的功能。

在Android应用中,可以有多个Activity,这些Activity组成了Activity栈(Stack),当前活动的Activity位于栈顶,之前的Activity被压入下面,成为非活动Activity,等待是否可能被恢复为活动状态。在Activity的生命周期中,有如表所示的4个重要状态。

状态 描述
活动状态 当前的Activity,位于栈顶,用户可见,并且可以获取焦点
暂停状态 失去焦点的Activity,仍然可见,但是在内存低的情况下,不能被系统killed
停止状态 该Activity被其他Activity所覆盖,不可见,但是仍然保存所有的状态和信息。当内存低的情况下,它将要被系统killed
销毁状态 该Activity结束,或Activity所在的Dalvik进程结束

onCreate()方法:在创建Activity时被回凋。该方法是最常见的方法,在创建Android项目时,会自动创建一个Activity,在该Activity中,默认重写了onCreate(Bundle savedInstanceState)方法,用于对该Activity执行初始化

onStart()方法:启动Activity时被回调,也就是当一个Activity变为显示时被回调。

onRestart()方法:重新启动Activity时被回调,该方法总是在onStartO方法以后执行

onPause()方法:暂停Activity时被回调。该方法需要被非常快速地执行,因为直到该方法执行完毕后,下一个Activity才能被恢复。在该方法中,通常用于持久保存数据。例如,当我们正在玩游戏时,突然来了一个电话,这时就可以在该方法中将游戏状态持久保存起来。

onResume()方法:当Activity由暂停状态恢复为活动状态时调用。调用该方法后,该Activity位于Activity栈的栈顶。该方法总是在onPauseO方法以后执行。

onStop()方法:停止Activity时被回调

onDestroy()方法:销毁Activity时被回调。

1、创建、配置、启动和关闭Activity

1.1、创建

(1)创建一个Activity,一般是继承android.app包中的Activity类,不过在不同的应用场景下,也可以继承Activity的子类。例如,在一个Activity中,只想实现一个列表,那么就可以让该Activity继承ListActivity;如果只想实现选项卡效果,那么就可以让该Activity继承TabActivity。创建一个名为MainAcrivity的继承Activity类的Activity,具体代码如下:

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
}

(2)重写需要的回调方法。通常情况下,都需要重写onCreate(0方法,并且在该方法中调用setContentView()方法设置要显示的视图。例如,在步骤(1)中创建的Activity中,重写onCreate()方法,并且设置要显示的视图的具体代码如下:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
}

1.2、配置

创建Activity后,还需要在AndroidManifest.xml文件中进行配置

具体的配置方法是在 标记中添加 标记。 标记的基本格式
如下:

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.ActivityTest">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

1.3、启动、关闭

在一个Android项目中,如果只有一个Activity,.那么只需要在AndroidManifest..xml文件中对其进行配置,并且将其设置为程序的入口。这样,当运行该项目时,将自动启动该Activity。否则,需要应用startActivity(方法来启动需要的Activity.startActivity()方法的语法格式如下:

public void startActivity(Intent intent){

    }
Intent intent = new Intent(MainActivity.this, NextActivity.this);
startActivity(intent);

在Android中,如果想要关闭当前的Activity,可以使用Activity类提供的finish()方法。finish()方法的语法格式如下

public void finish(){

    }

2、范例1:实现启动和关闭Activity

activity_main.xml

<?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"
    >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button1"
        android:text="开启下一个活动"/>

</LinearLayout>

detail.xml

<?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">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="欢迎来到详情页"
        android:id="@+id/textView"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button2"
        android:text="关闭详情页"/>

</LinearLayout>

MainActivity

package com.example.activitytest;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, DetailActivity.class);
                startActivity(intent);
            }
        });
    }
}

DetailActivity

package com.example.activitytest;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class DetailActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.detail);
        Button button = (Button) findViewById(R.id.button2);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }
}

最后在AndroidManifest.xml文件中注册DetailActivity

<activity
            android:name=".DetailActivity"
            android:exported="true"/>

3、多个Activity的使用

3.1、使用Bundle在Activity之间交换数据

当在一个Activity中启动另一个Activity时,经常需要传递一些数据。这时就可以通过Intent来实现,因为Intent通常被称为是两个Activity之间的信使,通过将要传递的数据保存在Intent中,就可以将其传递到另一个Activity中了。

在Android中,可以将要保存的数据存放在Bundle对象中,然后通过Intent提供的putExtras()方法将要携带的数据保存到Intent中。下面通过一个具体的实例介绍如何使用Bundle在Activity之间交换数据。

说明:Bundle是一个字符串值到各种Parcelable类型的映射,用于保存要携带的数据包。

实现用户注册界面,并跳转到另一个页面显示用户的注册信息

activity_main.xml

<?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
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/table1">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="用 户 名  :"
            android:id="@+id/textView1"/>
        <EditText
            android:layout_width="500px"
            android:layout_height="wrap_content"
            android:hint="请输入用户名"
            android:singleLine="true"
            android:id="@+id/editText1"/>
    </TableRow>
    <TableRow
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/table2">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="密       码 :"
            android:id="@+id/textView2"/>
        <EditText
            android:layout_width="500px"
            android:layout_height="wrap_content"
            android:hint="请输入密码"
            android:singleLine="true"
            android:id="@+id/editText2"/>
    </TableRow>
    <TableRow
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/table3">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="确认密码:"
            android:id="@+id/textView3"/>
        <EditText
            android:layout_width="500px"
            android:layout_height="wrap_content"
            android:hint="请确认密码"
            android:singleLine="true"
            android:id="@+id/editText3"/>
    </TableRow>
    <TableRow
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/table4">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button1"
            android:text="提交"/>
    </TableRow>

</TableLayout>

regist.xml

<?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">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text1"
        android:text=""/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text2"
        android:text=""/>

</LinearLayout>

MainActivity

package com.example.registerproject;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String name = ((EditText) findViewById(R.id.editText1)).getText().toString();
                String pwd = ((EditText) findViewById(R.id.editText2)).getText().toString();
                String repwd = ((EditText) findViewById(R.id.editText3)).getText().toString();
                if (!"".equals(name) && !"".equals(pwd) && !"".equals(repwd)){
                    if (!pwd.equals(repwd)){
                        Toast.makeText(MainActivity.this, "两次输入的密码不一样,请重新输入!", Toast.LENGTH_SHORT).show();
                        ((EditText) findViewById(R.id.editText2)).setText("");//清空密码
                        ((EditText) findViewById(R.id.editText3)).setText("");
                        ((EditText) findViewById(R.id.editText2)).requestFocus();//密码框获取焦点
                    }else {
                        Intent intent = new Intent(MainActivity.this, RegistActivity.class);
                        Bundle bundle = new Bundle();
                        bundle.putCharSequence("name", name);
                        bundle.putCharSequence("pwd", pwd);
                        intent.putExtras(bundle);
                        startActivity(intent);
                    }
                }else {
                    Toast.makeText(MainActivity.this, "请将注册信息填写完整!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

RegistActivity

package com.example.registerproject;

import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class RegistActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.regist);
        Intent intent = getIntent();
        Bundle bundle = intent.getExtras();
        TextView name = (TextView) findViewById(R.id.text1);
        String name1 = bundle.getString("name");
        name.setText("你的用户名为:"+name1);
        TextView pwd = (TextView) findViewById(R.id.text2);
        pwd.setText("你的密码为:"+bundle.getString("pwd"));
    }
}

最后在AndroidManifest.xml文件中注册DetailActivity

3.2、调用另一个Activity并返回结果

在Android应用开发时,有时需要在一个Activity中调用另一个Activity,当用户在第二个Activity中选择完成后,程序自动返回到第一个Activity中,第一个Activity必须能够获取并显示用户在第二个Activity中选择的结果;或者,在第一个Activity中将一些数据传递到第二个Activity,由于某些原因,又要返回到第一个Activity中,并显示传递的数据,如程序中经常出现的“返回上一步”功能。这时,也可以通过Intent和Bundle来实现。与在两个Acitivity之间交换数据不同的是,此处需要使用startActivityForResultO)方法来启动另一个Activity。下面通过一个具体的实例介绍如何调用另一个Activity并返回结果。

复制项目上一个,实现用户注册中的“返回上一步功能。

在MainActivity中添加常量,用于requestCode请求码

将原来使用startActivity()方法启动新Activity的代码修改为使用startActivityForResult()方法实现,这样就可以在启动一个新的Activity时,获取指定Activity返回的结果。

重写onActivityResult()方法,在该方法中,需要判断requestCode请求码和resultCode结果码是否与预先设置的相同

package com.example.registerproject;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    final int CODE = 0x77;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String name = ((EditText) findViewById(R.id.editText1)).getText().toString();
                String pwd = ((EditText) findViewById(R.id.editText2)).getText().toString();
                String repwd = ((EditText) findViewById(R.id.editText3)).getText().toString();
                if (!"".equals(name) && !"".equals(pwd) && !"".equals(repwd)){
                    if (!pwd.equals(repwd)){
                        Toast.makeText(MainActivity.this, "两次输入的密码不一样,请重新输入!", Toast.LENGTH_SHORT).show();
                        ((EditText) findViewById(R.id.editText2)).setText("");//清空密码
                        ((EditText) findViewById(R.id.editText3)).setText("");
                        ((EditText) findViewById(R.id.editText2)).requestFocus();//密码框获取焦点
                    }else {
                        Intent intent = new Intent(MainActivity.this, RegistActivity.class);
                        Bundle bundle = new Bundle();
                        bundle.putCharSequence("name", name);
                        bundle.putCharSequence("pwd", pwd);
                        intent.putExtras(bundle);
                        startActivityForResult(intent, CODE);
                        //startActivity(intent);
                    }
                }else {
                    Toast.makeText(MainActivity.this, "请将注册信息填写完整!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CODE && resultCode == CODE){
            Bundle bundle = data.getExtras();
            TextView textView = (TextView) findViewById(R.id.textView4);
            String wellcome = bundle.getString("wellcome");
            textView.setText(wellcome);
        }
    }
}

activity_main.xml

<?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
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/table1">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="用 户 名  :"
            android:id="@+id/textView1"/>
        <EditText
            android:layout_width="500px"
            android:layout_height="wrap_content"
            android:hint="请输入用户名"
            android:singleLine="true"
            android:id="@+id/editText1"/>
    </TableRow>
    <TableRow
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/table2">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="密       码 :"
            android:id="@+id/textView2"/>
        <EditText
            android:layout_width="500px"
            android:layout_height="wrap_content"
            android:hint="请输入密码"
            android:singleLine="true"
            android:id="@+id/editText2"/>
    </TableRow>
    <TableRow
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/table3">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="确认密码:"
            android:id="@+id/textView3"/>
        <EditText
            android:layout_width="500px"
            android:layout_height="wrap_content"
            android:hint="请确认密码"
            android:singleLine="true"
            android:id="@+id/editText3"/>
    </TableRow>
    <TableRow
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/table4">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button1"
            android:text="提交"/>
    </TableRow>
    <TableRow
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/table5">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            android:id="@+id/textView4"/>
    </TableRow>

</TableLayout>

regist.xml

<?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">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text1"
        android:text=""/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text2"
        android:text=""/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        android:text="返回"/>

</LinearLayout>

RegistActivity

package com.example.registerproject;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class RegistActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.regist);
        Intent intent = getIntent();
        Bundle bundle = intent.getExtras();
        TextView name = (TextView) findViewById(R.id.text1);
        String name1 = bundle.getString("name");
        name.setText("你的用户名为:"+name1);
        TextView pwd = (TextView) findViewById(R.id.text2);
        pwd.setText("你的密码为:"+bundle.getString("pwd"));
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent1 = new Intent(RegistActivity.this, MainActivity.class);
                Bundle bundle1 = new Bundle();
                bundle1.putCharSequence("wellcome", "欢迎回来");
                intent1.putExtras(bundle1);
                setResult(0x77, intent1);
                finish();
            }
        });
    }
}

3.3、范例1:根据身高计算标准体重

修改Activity_main

<?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"
    >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="性别"
        android:textSize="50px" />
    <RadioGroup
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:id="@+id/radioGroup1">
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="男"
            android:id="@+id/radio1"
            android:checked="true"/>
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="女"
            android:id="@+id/radio2"/>
    </RadioGroup>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="身高"
        android:textSize="50px" />
    <EditText
        android:layout_width="300px"
        android:layout_height="wrap_content"
        android:id="@+id/editText"
        android:hint="请输入身高"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        android:text="提交"/>
</LinearLayout>

创建next_activity.xml,用于显示计算身高后的结果

<?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">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text1"
        android:text=""/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text2"
        android:text=""/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text3"
        android:text=""/>

</LinearLayout>
package com.example.activityfanli01;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Info info = new Info();
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if ("".equals(((EditText) findViewById(R.id.editText)).getText().toString())){
                    Toast.makeText(MainActivity.this, "请输入你的身高!", Toast.LENGTH_SHORT).show();
                    ((EditText) findViewById(R.id.editText)).getFocusable();
                    return;
                }
                String s = ((EditText) findViewById(R.id.editText)).getText().toString();
                Integer heigh = Integer.valueOf(s);
                info.setHeigh(heigh);
                RadioGroup group = (RadioGroup) findViewById(R.id.radioGroup1);
                for (int i = 0; i < group.getChildCount(); i++) {
                    RadioButton radioButton = (RadioButton) group.getChildAt(i);
                    if (radioButton.isChecked()){
                        info.setSex(radioButton.getText().toString());
                        break;
                    }
                }
                Bundle bundle = new Bundle();
                bundle.putSerializable("info", info);
                Intent intent = new Intent(MainActivity.this, NextActivity.class);
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });
    }
}
package com.example.activityfanli01;

import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

public class NextActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_next);
        Intent intent = getIntent();
        Bundle extras = intent.getExtras();
        Info info = (Info) extras.getSerializable("info");
        TextView heigh = (TextView) findViewById(R.id.text1);
        heigh.setText("你的身高为:"+info.getHeigh());
        TextView sex = (TextView) findViewById(R.id.text2);
        sex.setText("你的性别为:"+info.getSex());
        TextView wigth = (TextView) findViewById(R.id.text3);
        wigth.setText("你的性别为:"+getWight(info.getSex(), (int) info.getHeigh()));
    }
    public Double getWight(String sex, Integer heigh){
        double wight = 0;
        if (sex.equals("男")){
            wight = (heigh - 80) * 0.7;
        }else {
            wight = (heigh - 70) * 0.6;
        }
        return wight;
    }
}

3.4、选择带头像的注册页面

创建Android项目,实现带选择头像的用户注册页面,打开新的Activity选择头像,并将选择的头像返回到原Activity中。

<?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="horizontal">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1">
        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TableRow
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <TextView
                    android:layout_width="wrap_content"
                    android:gravity="center"
                    android:layout_height="match_parent"
                    android:text="用户名:"/>
                <EditText
                    android:layout_width="400px"
                    android:layout_height="match_parent"
                    android:id="@+id/edit01"
                    android:inputType="textPersonName"/>
            </TableRow>
            <TableRow
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <TextView
                    android:layout_width="wrap_content"
                    android:gravity="center"
                    android:layout_height="match_parent"
                    android:text="密    码:"/>
                <EditText
                    android:layout_width="400px"
                    android:layout_height="match_parent"
                    android:id="@+id/edit02"
                    android:inputType="textPassword"/>
            </TableRow>
        </TableLayout>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/image01"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button"
            android:text="选择头像"/>
    </LinearLayout>

</LinearLayout>
<?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">

    <GridView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/grid"
        android:numColumns="4"/>

</LinearLayout>
package com.example.activitytest003;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, NextActivity.class);
                startActivityForResult(intent, 1);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 || resultCode == 1){
            ImageView imageView = (ImageView) findViewById(R.id.image01);
            int imageId = data.getExtras().getInt("imageId");
            imageView.setImageResource(imageId);
        }
    }
}
package com.example.activitytest003;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.Nullable;

public class NextActivity extends Activity {

    final int[] imageId = new int[]{
            R.drawable.icon07, R.drawable.icon08, R.drawable.icon09, R.drawable.icon10,
            R.drawable.icon07, R.drawable.icon08, R.drawable.icon09, R.drawable.icon10,
            R.drawable.icon07, R.drawable.icon08, R.drawable.icon09, R.drawable.icon10,
            R.drawable.icon07, R.drawable.icon08, R.drawable.icon09, R.drawable.icon10};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_next);

        GridView gridView = (GridView) findViewById(R.id.grid);

        gridView.setAdapter(new BaseAdapter() {
            @Override
            public int getCount() {
                return imageId.length;
            }

            @Override
            public Object getItem(int i) {
                return i;
            }

            @Override
            public long getItemId(int i) {
                return i;
            }

            @Override
            public View getView(int i, View view, ViewGroup viewGroup) {
                ImageView imageView;
                if (view == null){
                    imageView = new ImageView(NextActivity.this);
                }else {
                    imageView = (ImageView) view;
                }
                imageView.setImageResource(imageId[i]);
                return imageView;
            }
        });

        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                new AlertDialog.Builder(NextActivity.this)
                        .setPositiveButton("确认", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int a) {
                                Intent intent = new Intent();
                                Bundle bundle = new Bundle();
                                bundle.putInt("imageId", imageId[i]);
                                intent.putExtras(bundle);
                                setResult(1, intent);
                                finish();
                            }
                        })
                        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                Toast.makeText(NextActivity.this, "请选择其他图片", Toast.LENGTH_SHORT).show();
                            }
                        }).create().show();
            }
        });
    }
}

4、使用Fragment

Fragment是Android3.0新增的概念,其中文意思是碎片,它与Activity十分相似,用来在一个Activity中描述一些行为或一部分用户界面。使用多个Fragment可以在一个单独的Activity中建立多个UI面板,也可以在多个Activity中重用Fragment。一个Fragment必须被嵌入到一个Activity中,它的生命周期直接受其所属的宿主Activity的生命周期影响。

例如,当Activity被暂停时,其中的所有Fragment也被暂停;当Activity被销毁时,所有隶属于它的Fragment也将被销毁。然而,当一个Activity处于resumed状态(正在运行)时,可以单独地对每一个Fragment进行操作,如添加或删除等。

4.1、创建fragment

要创建一个Fragment,,必须创建一个Fragment的子类,或者继承自另一个已经存在的Fragment的子类。例如,要创建一个名称为NewsFragment的Fragment,,并重写onCreateView()方法,可以使用下面的代码:

public class NewFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_new, container, true);
        return view;
    }
}
<?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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是一个fragment"/>
</LinearLayout>

4.2、在Acyivity中添加fragment

向Activity中添加Fragment,,有两种方法:一种是直接在布局文件中添加,将Fragment作为Activity整个布局的一部分;另一种是当Activity运行时,将Fragment放入Activity布局中。下面分别进行介绍。

4.2.1、在布局文件中添加fragment

说明:在 标记中,android:name属性用于指定要添加的Fragment.

<?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="horizontal">
    <fragment
        android:name="com.example.fragmentproject.NewFragment"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:id="@+id/fragment1"/>
    <fragment
        android:layout_weight="2"
        android:layout_width="20dp"
        android:layout_height="match_parent"
        android:id="@+id/fragment2"
        android:name="com.example.fragmentproject.NewFragment"/>

</LinearLayout>

4.2.2、当Activity运行时添加fragment

当Activity运行时,也可以将Fragment添加到Activity的布局中,实现方法是获取一个FragmentTransaction的实例,然后使用addO方法添加一个Fragment,.addO方法的第一个参数是Fragment要放入的ViewGroup(由ResourceID指定),第二个参数是需要添加Fragment,.最后为了使改变生效,还必须调用commit(0方法提交事务。例如,要在Activity运行时添加一个名称为DetailFragment的Fragment,可以使用下面的代码:

NewFragment newFragment = new NewFragment();
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.add(androidx.appcompat.R.id.content, newFragment);
        fragmentTransaction.commit();

实例

Fragment比较强大的功能之一就是可以合并两个Activity,从而让这两个Activity在一个屏幕上显示

例3.4创建Android项目,实现在一个屏幕上显示标题列表及选定标题对应的详细内容。

(1)创建布局文件。为了让该程序既支持横屏,又支持竖屏,所以需要创建两个布局文科,芬别是在res layout目录中创建的main.xml和在res\layout-land目录中创建的main.xml。其中在layout目录中创建的main.xml是支持手机时用的布局文件,在该文件中,只包括一个Fragment::在layout-land目录中创建的是支持平板电脑时用的布局文件,在该文件中,需要在水平线性布局管理器中添加一个Fragment和一个FrameLayout。。在layout--land目录中创建的main.xml的具体代码如下:

<?xml version="1.0" encoding="utf-8"?>
<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:orientation="horizontal"
    tools:ignore="MissingDefaultResource">
    
    <fragment
        class="com.example.fragmentapplication.ListFragment"
        android:layout_weight="1"
        android:layout_width="0px"
        android:layout_height="match_parent"
        android:id="@+id/tetils"/>
    <FrameLayout
        android:layout_weight="2"
        android:layout_width="0px"
        android:layout_height="match_parent"
        android:background="?android:attr/detailsElementBackground"/>
</LinearLayout>

(2)创建一个名称为Data的final类,在该类中创建两个静态的字符串数组常量,分别用于保存标题和详细内容。Data类的关键代码如下:

package com.example.fragmentapplication;

public final class Data {
    public static final String[] TITLES = {"java", "c", "python", "PHP"};

    public static final String[] DETAIL = {
            "JaVa是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念," +
                    "因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地" +
                    "实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程",
            "C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、" +
                    "处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。" +
                    "尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括" +
                    "类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。",
            "Python会・范苏于1990年代设计,作为一门叫做ABC语言的替代品。[1]Python提供了高效的高级数据结构,还能" +
                    "简单有效地面向对象编程。Python语法和动态类型以及解释型语言的本质,使它成为多数平台上写脚本" +
                    "和快速开发应用的编程语言随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。",
            "PHP(PHP:Hypertext Preprocessor)即“超文本预处理器”,是在服务器端执行的脚本语言,尤其适用于" +
                    "Web开发并可嵌入HTML中。PHP语法学习了C语言,吸纳Java和PerI多个语言的特色发展出自己的特色语法," +
                    "并根据它们的长项持续改进提升自己,例如jva的面向对象编程,该语言当初创建的主要目标是让开发人员快速" +
                    "编写出优质的web网站。[1-2]PHP同时支持面向对象和面向过程的开发,使用上非常灵活。"
    };
}

(3)创建一个继承自ListFragment的ListFragment,用于显示一个标题列表,并且设置当选中其中的一个列表项时,显示对应的详细内容(如果为横屏,则创建一个DetialFragment的实例来显示,否则创建一个Activity来显示)。ListFragment类的具体代码如下:

package com.example.fragmentapplication;

import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

public class ListFragment extends androidx.fragment.app.ListFragment{
    boolean dualPane;
    int curCheckPostion = 0;
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //为列表设置适配器
        setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_checked, Data.TITLES));
        //获取布局文件中的FragLayout帧布局管理器
        View view = getActivity().findViewById(R.id.detail);
        //判断是否同一屏显示列表和描述
        dualPane = view != null && view.getVisibility() == View.VISIBLE;
        if (savedInstanceState != null){
            curCheckPostion = savedInstanceState.getInt("curChoice", 0);
        }
        if (dualPane){
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            showDetails(curCheckPostion);
        }
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("curChoice", curCheckPostion);
    }

    @Override
    public void onListItemClick(@NonNull ListView l, @NonNull View v, int position, long id) {
        showDetails(position);
    }

    void showDetails(int curCheckPostion) {
        if (dualPane){
            getListView().setItemChecked(curCheckPostion, true);
            DetailsFragment detailsFragment = (DetailsFragment) getFragmentManager().findFragmentById(R.id.detail);
            if (detailsFragment == null || detailsFragment.getShowIndex() != curCheckPostion){
                detailsFragment = DetailsFragment.newInstancd(curCheckPostion);
                FragmentTransaction beginTransaction = getFragmentManager().beginTransaction();
                beginTransaction.replace(R.id.detail, detailsFragment);
                beginTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                beginTransaction.commit();
            }
        }else {
            Intent intent = new Intent(getActivity(), MainActivity.DetailActivity.class);
            intent.putExtra("index", curCheckPostion);
            startActivity(intent);
        }
    }
}
package com.example.fragmentapplication;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class DetailsFragment extends Fragment {

    public static DetailsFragment newInstancd(int curCheckPostion) {
        DetailsFragment fragment = new DetailsFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("index", curCheckPostion);
        fragment.setArguments(bundle);
        return fragment;
    }

    public int getShowIndex() {
        return getArguments().getInt("index", 0);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (container == null){
            return null;
        }
        ScrollView scrollView = new ScrollView(getActivity());
        TextView textView = new TextView(getActivity());
        textView.setPadding(10, 10, 10, 10);
        scrollView.addView(textView);
        textView.setText(Data.DETAIL[getShowIndex()]);
        return scrollView;
    }
}

(5)打开默认创建的MainActivity,在该类中创建一个内部类,用于在手机界面中通过Activity显示详细内容,具体代码如下:

package com.example.fragmentapplication;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.content.res.Configuration;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public static class DetailActivity extends Activity {
        @SuppressLint("ResourceType")
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.id.detail);
            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
                finish();
                return;
            }
            if (savedInstanceState == null){
                DetailsFragment detailsFragment = new DetailsFragment();
                detailsFragment.setArguments(getIntent().getExtras());
                getFragmentManager().beginTransaction().add(android.R.id.content, detailsFragment).commit();
            }
        }
    }
}

(6)在AndroidManifest.xml文件中配置DetailActivity,配置的主要属性有Activity使用的标签和实现类,具体代码如下:

<activity
            android:name=".MainActivity$DetailActivity"


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM