初识Parcelable
关于Parcelable
Parcelable接口主要应用于Controller之间传递数据时使用
创建项目
本文为学习类文档,通过学习B站up主longway777的视频,再加上自己的总结与理解的学习类文章,如有侵权,请联系博主进行删除
创建一个项目,在首页面中设置数据,点击按钮进行传递数据,并将数据带入第二个界面中进行显示。
设计student类
包含name,age,score(math,student)实现Parcelable接口,无需自己写代码,根据提示添加Parcelable接口
import android.os.Parcel;
import android.os.Parcelable;
public class Student implements Parcelable{ //声明实现Parcelable接口
private String name;
private int age;
private Score score;
public Student(String name, int age, Score score) {
this.name = name;
this.age = age;
this.score = score;
}
protected Student(Parcel in) {
name = in.readString();
age = in.readInt();
score = in.readParcelable(Score.class.getClassLoader());
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
dest.writeParcelable(score, flags);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Student> CREATOR = new Creator<Student>() {
@Override
public Student createFromParcel(Parcel in) {
return new Student(in);
}
@Override
public Student[] newArray(int size) {
return new Student[size];
}
};
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Score getScore() {
return score;
}
public void setScore(Score score) {
this.score = score;
}
}
class Score implements Parcelable { //点击类的名称添加implementation
private int math;
private int English;
public Score(int math, int english) {
this.math = math;
English = english;
}
protected Score(Parcel in) {
math = in.readInt();
English = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(math);
dest.writeInt(English);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Score> CREATOR = new Creator<Score>() {
@Override
public Score createFromParcel(Parcel in) {
return new Score(in);
}
@Override
public Score[] newArray(int size) {
return new Score[size];
}
};
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return English;
}
public void setEnglish(int english) {
English = english;
}
}
至此Parcelable就构建完成,当我们想要从一个进程将数据传递到另一个进程时,便可以遵从该接口进行传递
设计界面
- 首界面
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/editTextEnglish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="English"
android:inputType="number"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintEnd_toEndOf="@+id/editTextMath"
app:layout_constraintStart_toStartOf="@+id/editTextMath"
app:layout_constraintTop_toBottomOf="@+id/editTextMath" />
<EditText
android:id="@+id/editTextMath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Math"
android:inputType="number"
app:layout_constraintBottom_toTopOf="@+id/editTextEnglish"
app:layout_constraintEnd_toEndOf="@+id/editTextAge"
app:layout_constraintStart_toStartOf="@+id/editTextAge"
app:layout_constraintTop_toBottomOf="@+id/editTextAge" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="459dp" />
<EditText
android:id="@+id/editTextName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Name"
android:inputType="textPersonName"
app:layout_constraintBottom_toTopOf="@+id/editTextAge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/editTextAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Age"
android:inputType="number"
app:layout_constraintBottom_toTopOf="@+id/editTextMath"
app:layout_constraintEnd_toEndOf="@+id/editTextName"
app:layout_constraintStart_toStartOf="@+id/editTextName"
app:layout_constraintTop_toBottomOf="@+id/editTextName" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="@+id/editTextEnglish"
app:layout_constraintStart_toStartOf="@+id/editTextEnglish"
app:layout_constraintTop_toBottomOf="@+id/editTextEnglish" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
为了防止使用控件时造成大量的findViewById,再次使用之前学过的dataBinding
在gradle中设置并sync同步:
android {
...
dataBinding.enabled true
}
并将layout转换为databinding layout格式
在MainActivity中使用ActivityMainBinding来进行界面的绑定即可:
ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
- 第二个界面
为了模拟进程中的通信,创建第二个Activity并创建第二个Layout,并同理转换dataBinding格式和在Main2Activity.java中使用DataBinding界面绑定
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main2Activity">
<TextView
android:id="@+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/textViewAge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textViewAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/textViewMath"
app:layout_constraintEnd_toEndOf="@+id/textViewName"
app:layout_constraintStart_toStartOf="@+id/textViewName"
app:layout_constraintTop_toBottomOf="@+id/textViewName" />
<TextView
android:id="@+id/textViewMath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/textViewEnglish"
app:layout_constraintEnd_toEndOf="@+id/textViewAge"
app:layout_constraintStart_toStartOf="@+id/textViewAge"
app:layout_constraintTop_toBottomOf="@+id/textViewAge" />
<TextView
android:id="@+id/textViewEnglish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/guideline2"
app:layout_constraintEnd_toEndOf="@+id/textViewMath"
app:layout_constraintStart_toStartOf="@+id/textViewMath"
app:layout_constraintTop_toBottomOf="@+id/textViewMath" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="450dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
//setContentView(R.layout.activity_main2); //这个不用
ActivityMain2Binding binding = DataBindingUtil.setContentView(this,R.layout.activity_main2);
设计逻辑代码
MainActivity.java中
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.example.parcelable.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
final ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = binding.editTextName.getText().toString();
int age = Integer.valueOf(binding.editTextAge.getText().toString());
int math = Integer.valueOf(binding.editTextMath.getText().toString());
int english = Integer.parseInt(binding.editTextEnglish.getText().toString()); //Integer.valueOf()与Integer.parseInt()现在没有区别了
Student student = new Student(name,age,new Score(math,english));
Intent intent = new Intent(MainActivity.this,Main2Activity.class);
//intent.putExtra("student",student); //由于student类已经使用了Parcelable接口可以直接使用,但不符和代码习惯,应该如下:
Bundle bundle = new Bundle();
bundle.putParcelable("student",student); //数据打包为bundle,两个参数为:名称,
intent.putExtra("data",bundle); //再把bundle放入intent中
startActivity(intent); //切换Activity
}
});
}
}
Main2Activity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import android.content.Intent;
import android.os.Bundle;
import com.example.parcelable.databinding.ActivityMain2Binding;
public class Main2Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main2);
ActivityMain2Binding binding = DataBindingUtil.setContentView(this,R.layout.activity_main2);
Intent intent = getIntent(); //获取
Bundle bundle = intent.getBundleExtra("data");
Student student = bundle.getParcelable("student");
binding.textViewName.setText(student.getName());
binding.textViewAge.setText(String.valueOf(student.getAge()));
binding.textViewMath.setText(String.valueOf(student.getScore().getMath()));
binding.textViewEnglish.setText(String.valueOf(student.getScore().getEnglish()));
}
}
运行项目
在第一个界面中填写数据,点击按钮会在第二个界面中显示,实现数据在不同Activity中的传递(即使两个界面在不同的process中,这种方法依然是可以实现的,放弃远古时代的MyApplication吧!)