1. 程式人生 > 其它 >四大元件之Activity

四大元件之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"