移动应用开发入门级必看,用活动打造属于你的页面。
重要的更新公告
!!!GDPU的小伙伴,感谢大家的支持,希望到此一游的帅哥美女能有所帮助。本学期的前端框架及移动应用,采用专栏订阅量达到50才开始周更了哦( •̀ .̫ •́ )✧
编译器界面
移动端小白可以看一下,大致了解一下andriod studio的界面布局。在新建工程前,记得要下载好这个编译器还有JDK与SDK,此外,多数用的是虚拟设备,所以还要在device manager里面下载一个虚拟设备便于调试运行。
然后先学一下新建工程,这个敲过代码的都很熟悉了,点击到new project,入门先选empty的布局。
接着输入你的文件名跟路径,还有可选是用java还是kotlin开发的。新建完后,刚入门,看着都晕了,怎么敲,先了解大致要学的文件。
这里选中project,来到工程目录。然后会有很多个文件,版本不同可能有些许差别。
在那么多文件中找哪个,作为刚入门的,对准app展开就行了,其它的可以先当配置文件。然后主要的就是里面的main文件。
其中,java文件夹为后端代码放的文件夹,res文件夹放多种资源,包括页面设计代码的编写可放在layout文件夹。然后这里的layout前端页面是支持可视化编程的,所以即使还不太会敲也不要紧哦。可以点击里面默认的xml文件,找到编译器的一些选项帮助开发。
找到这几个选项,版本不同不一定在这个位置。点design进行可视化界面编辑,即在palatte面板找到相应的一些ui组件拖进界面即可,在attributes中设置布局的属性,然后component tree是用来显示页面用的ui控件。点击code即切换到代码模式,andriod中用xml编写,大家可以结合使用设计界面。
然后调好虚拟设备点击运行,即可在设备上显示应用。
在这里写一个运行不了的日志,控制台显示RES_TABLE_TYPE_TYPE entry offsets overlap actual entry data,Failed to load resources table,是sdk与虚拟设备不符的问题。
找到app下的build.gradle,点击查看sdk版本。
这里的sdk版本要一致,然后调小一点就可以了。
活动的创建
1.启动与销毁Activity
创建一个名为FristActivity的活动
在Manifest文件中注册该活动
重写onCreate方法,并在改方法中加载布局first_layout。
创建布局first_layout.xml,在该布局中添加一个Button控件
在onCreate方法中获得布局中Button的引用
单击Button退出当前Activity
重写onDestroy方法,并在该方法中打印该Activity退出的信息:Activity名称+“退出了,bye!”
先新建一个空白活动。
看准你设置好的activity name与layout name,代码会自动生成关联的,如果想修改对应的布局文件修改activity代码中对应文件即可。launcher是主页面才需设置的,实验中这个是主页所以勾上,后面创建的不用。
这里activity的代码主要用了java,kotlin也在注释中可参考。注意,FristActivity代码与first_layout是主页代码,包含了后面几题,不再重复打印,里面也有详细注释可参考。
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;
public class FirstActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
Button button1 = findViewById(R.id.button1);
Button Button1 = findViewById(R.id.Button1);
Button Button2 = findViewById(R.id.Button2);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish(); // 退出当前活动
}
});
//kotlin
// val button1: Button = findViewById(R.id.button1)
// button1.setOnClickListener {
// finish() // 退出当前活动
// }
Button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 显式 Intent 启动 SecondActivity1
Intent intent = new Intent(FirstActivity.this, SecondActivity1.class);
intent.putExtra("message", "Hello SecondActivity");//活动传递数据
startActivity(intent);
}
});
Button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 隐式 Intent 启动 SecondActivity2
Intent intent = new Intent("com.example.SECOND_ACTIVITY");
intent.putExtra("message", "Hello SecondActivity");
startActivity(intent);
}
});
Button button3 = findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, ThirdActivity.class);
startActivity(intent); // 启动 ThirdActivity
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("FirstActivity", "FirstActivity退出了,bye!");
}
//kotlin
//override fun onDestroy() {
// super.onDestroy()
// Log.d("FirstActivity", "FirstActivity退出了,bye!")
//}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
//活动的创建
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1 "/>
//传递数据
<Button
android:id="@+id/Button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SecondActivity1" />
<Button
android:id="@+id/Button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SecondActivity2" />
//保存恢复
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Activity3" />
</LinearLayout>
最好分开写,这题点击button1。
这题打开控制台的logcat,可查看输出退出的信息。
活动传递数据
创建SecondActivity1和SecondActivity2, SecondActivity1加载布局second_layout1,SecondActivity2加载布局second_layout2。在上题的FirstActivity的布局中添加两个按钮(Button1, Button2),点击Button1时使用显式Intent启动SecondActivity1,点击Button2时使用隐式Intent启动SecondActivity2;此外从FirstActivity中传递一个字符串”Hello SecondActivity”到SecondActivity中,并在SecondActivity中用TextView控件显示。(实验报告中只需写出onCreate方法,实现该功能的代码写在onCreate方法中)
使用显式Intent启动Activity
使用隐式Intent启动Activity
创建活动跟上题类似,然后就是intent的编写,FristActivity加上intent并调用putExtra方法传递数据,然后在SecondActivity进行接收数据。intent的显示启动与隐式启动的区别为,显式 Intent 指定要启动的组件的名称, 而隐式 Intent 指定要执行的操作和数据类型。题中还要在对应的layout代码写一个TextView控件,不会写可以在design界面拉一个TextView控件到界面上。
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class SecondActivity1 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout1);
String message = getIntent().getStringExtra("message");
TextView textView = findViewById(R.id.textView1);
textView.setText(message);
// val message = intent.getStringExtra("message")
// val textView: TextView = findViewById(R.id.textView)
// textView.text = message
}
}
<?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"
android:padding="16dp">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
</LinearLayout>
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class SecondActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout2);
String message = getIntent().getStringExtra("message");
TextView textView = findViewById(R.id.textView2);
textView.setText(message);
// val message = intent.getStringExtra("message")
// val textView: TextView = findViewById(R.id.textView)
// textView.text = message
}
}
<?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"
android:padding="16dp">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
</LinearLayout>
此外,不要忘了在AndroidManifest进行活动的注册。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.t2">
<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.T2">
<activity
android:name=".ThirdActivity"
android:exported="false" />
<activity android:name=".SecondActivity1" />
<activity
android:name=".SecondActivity2"
android:exported="true">
<intent-filter>
<action android:name="com.example.SECOND_ACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".FirstActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
点击两个按钮,可跳转到相应的页面,查看Hello SecondActivity的呈现。
保存恢复活动状态
假设ThirdActivity中有一个EditText输入框,请按照以上说的方法实现保存和恢复Activity中EditText中的文字。
同样,创建一个活动,然后在FirstActivity写intent跳过去,写好对应的xml与活动的注册。然后,编写保存恢复活动状态在ThirdActivity。
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.EditText;
public class ThirdActivity extends AppCompatActivity {
private static final String STATE_TEXT = "saved_text";
private EditText mEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.third_layout);
mEditText = findViewById(R.id.editText);
// 检查是否为重新创建的实例
if (savedInstanceState != null) {
// 恢复 EditText 中的文本
String savedText = savedInstanceState.getString(STATE_TEXT);
mEditText.setText(savedText);
Log.d("ThirdActivity", "Restoring text1: " + savedText);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// 保存 EditText 中的文本
String textToSave = mEditText.getText().toString();
outState.putString(STATE_TEXT, textToSave);
Log.d("ThirdActivity", "Saving text: " + textToSave);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// 恢复文本
String savedText = savedInstanceState.getString(STATE_TEXT);
mEditText.setText(savedText);
Log.d("ThirdActivity", "Restoring text2: " + savedText);
}
}
<?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"
android:padding="16dp">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="输入文本" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="提交"
android:layout_marginTop="16dp"/>
</LinearLayout>
当我们的activity开始Stop,系统会调用 onSaveInstanceState() ,Activity可以用键值对的集合来保存状态信息。当Activity从Destory中重建,我们可以从系统传递的Activity的Bundle中恢复保存的状态。 onCreate() 与 onRestoreInstanceState() 回调方法都接收到了同样的Bundle,里面包含了同样的实例状态信息。
点击旋转按钮,logcat切换一下,然后看打印出的文本。
实验心得
写了个很长的活动。