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
說明:在
<?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"