通过 2nd activity 中的 Parcelable 通过 intent 从检索到的 ArrayList 中获取 ArrayList 的元素
Get elements of ArrayList from retrieved ArrayList via intent via Parcelable in 2nd activity
我正在尝试构建一个简单的 android 来模拟用卡片学习词汇。为了获得最终的应用程序,我将通过学习新事物和添加新事物来逐步添加功能和复杂性。
我要告诉你我被困在哪里,但首先,到目前为止,这是我的应用程序应该做的(我离我想要的地方还很远,但是你不必担心这个。):
此时应用程序应该执行以下操作:
1) 在MainActivity中:
a) 创建一个包含 3 个实例的数组
Parcelable 接口(class VocCard 实现 Parcelable),VocCard[]
voc1,在这种情况下。由于 class VocCard 实现了 Parcelable,一个
3个实例的构建获得包裹
- b) 创建一个名为 vocCardList 的 VocCard 类型的 ArrayList 并添加
voc1 的所有 3 个元素到 vocCardList。
- c) 创建一个开始按钮的实例,它为
单击时启动第二个 activity 称为 PracticeActivity。
- d) 将带有 Parcelable 的 ArrayList vocCardList 添加到
意图。
2) 在 PracticeActivity
- a) 获取 MainActivity 创建的意图。
- b) 从 intent
中检索 ArrayList vocCardList
- c) 获取vocCardsList的任意元素并赋值一个类型的变量
VocCard 给它。
- d) 通过调用 Voccard 实例检索分配的 Voccard 实例的值
方法。
- e) 通过将 TextView 设置为值的字符串来显示该值
值。
- f) 创建一个 Button nextButton,它创建一个开始的意图
第二个 activity PracticeActivity 再次作为某种递归。
- g) 添加 ArrayList vocCardList with parcelable 到 intent。
- h) 重复 2) a)-g) 直到 App 被 closing-icon 关闭。
我目前停留在 2) c),因为该应用程序只能按照上述索引 0 的方式工作。只有 VocCard card0 = vocCardList1.get( 0);有效,vocCardList1.get(1),或 vocCardList1.get(2);不要,尽管 1 和 2 在 ArrayList 边界内。
奇怪的是,使用索引 1 和索引 2 的运行时异常消息不一样:
与 vocCardList1.get(1):java.lang.ClassCastException: java.lang.String cannot be cast to com.undiclosed.smartcards.VocCard
与 vocCardList1.get(2):java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.undisclosed.smartcards.VocCard.returnVocForeign()' on a null object reference
问题:
为什么我不能按照预期的方式访问 ArrayList 的元素?当我在网上搜索时,我可能在寻找错误的东西。
MainActivity.java:
package com.undisclosed123.smartcards;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<VocCard> vocCardList;
private String[] voc_f = {"bread","apple","water"};
private String[] voc_n = {"pain","pomme","eau"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Create VocCards and add to List
vocCardList = new ArrayList<VocCard>();
VocCard[] voc1 = new VocCard[3];
Parcel in = Parcel.obtain();
for(int i = 0; i < 3; i++){
voc1[i] = new VocCard(in);
voc1[i].setVocForeign(voc_f[i]);
voc1[i].setVocNative(voc_n[i]);
vocCardList.add(voc1[i]);
}
// Create Intent and assign the parcelable List for sending to second activity on btn click
Button startBtn = (Button) findViewById(R.id.button);
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
@SuppressWarnings("unchecked")
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, PracticeActivity.class);
intent.putParcelableArrayListExtra("voc1",(ArrayList)vocCardList);
getApplicationContext().startActivity(intent);
}
});
}
}
及以下,PracticeActivity.java:
(很抱歉被注释掉的大部分内容,我想这可以帮助传达我进一步的意图 class)
package com.undisclosed123.smartcards;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
public class PracticeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice);
// Get the Intent that started this activity and extract the string
Intent intent = getIntent();
final ArrayList<VocCard> vocCardList1 = intent.getParcelableArrayListExtra("voc1"); //
//Get the Data from the VocCards
//VocCard card4count = vocCardList1.get(2);
// card4count.increaseCount();
//int count = card4count.getCount();
/* if(count >= vocCardList1.size()){
// TODO
//Create new intent for EndPracticeActivity
//makeshift statement
count--;
}*/
VocCard card0 = vocCardList1.get(2);
// VocCard card1 = vocCardList1.get(1);
String test1 = card0.returnVocForeign();
// card0.increaseCount();
// String test1 = "test1";
//Make a TextView display the transfered String
TextView textView = findViewById(R.id.textView);
textView.setText(test1);
//Create another intent that recalls same activity recursively
Button nextBtn = (Button) findViewById(R.id.button2);
nextBtn.setOnClickListener(new View.OnClickListener() {
@Override
@SuppressWarnings("unchecked")
public void onClick(View v) {
Intent intent = new Intent(PracticeActivity.this, PracticeActivity.class);
intent.putParcelableArrayListExtra("voc1",(ArrayList)vocCardList1);
getApplicationContext().startActivity(intent);
}
}); /**/
}
}
最后,VocCard.java:
package com.undisclosed123.smartcards;
import android.os.Parcel;
import android.os.Parcelable;
public class VocCard implements Parcelable {
private String voc_foreign;
private String voc_native;
private boolean learned;
private int error_level;
private static int counter;
public String returnVocForeign(){
return voc_foreign;
}
public void setVocForeign(String voc_f){
voc_foreign = voc_f;
}
public String returnVocNative(){
return voc_native;
}
public void setVocNative(String voc_n){
voc_native = voc_n;
}
public boolean checkLearned(){
return learned;
}
public int getErrorLevel(){
return error_level;
}
public void makeLearned(){
learned = true;
}
public void increaseErrorLevel(){
error_level++;
}
public int getCount(){
return counter;
}
public void increaseCount(){
counter++;
}
public VocCard(Parcel in) {
voc_foreign = in.readString();
voc_native = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(voc_foreign);
dest.writeString(voc_native);
dest.writeInt((Boolean) learned ? 1 : 0);
dest.writeInt(error_level);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<VocCard> CREATOR = new Creator<VocCard>() {
@Override
public VocCard createFromParcel(Parcel in) {
return new VocCard(in);
}
@Override
public VocCard[] newArray(int size) {
return new VocCard[size];
}
};
}
问题在于将数据写入 Parcel
并从中读取数据。
public class VocCard implements Parcelable {
...
...
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(voc_foreign);
dest.writeString(voc_native);
dest.writeInt(learned ? 1 : 0);
dest.writeInt(error_level);
}
/**
* This constructor is invoked by the method
* createFromParcel(Parcel source) of the object CREATOR.
*
* The order and number of writing and reading data to and from
* Parcel should be same
**/
private VocCard(Parcel in) {
voc_foreign = in.readString();
voc_native = in.readString();
learned = in.readInt() == 1;
error_level = in.readInt();
}
/**
* A constructor that initializes the VocCard object.
**/
VocCard(String voc_foreign, String voc_native) {
this.voc_foreign = voc_foreign;
this.voc_native = voc_native;
}
...
...
}
MainActivity
内部 onCreate
几乎没有变化
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
...
//Create VocCards and add to List
mVocCardList = new ArrayList<>(3);
for (int i = 0; i < 3; i++) {
mVocCardList.add(new VocCard(voc_f[i], voc_n[i]));
}
Button startBtn = (Button) findViewById(R.id.button);
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, PracticeActivity.class);
intent.putParcelableArrayListExtra("voc1", (ArrayList<? extends Parcelable>) mVocCardList);
startActivity(intent);
}
});
}
现在在PracticeActivity
中获取VocCard
列表
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
...
final ArrayList<VocCard> vocCardList = getIntent().getParcelableArrayListExtra("voc1");
final VocCard card = vocCardList.get(2);
String test = card.getVocForeign();
...
...
}
我正在尝试构建一个简单的 android 来模拟用卡片学习词汇。为了获得最终的应用程序,我将通过学习新事物和添加新事物来逐步添加功能和复杂性。
我要告诉你我被困在哪里,但首先,到目前为止,这是我的应用程序应该做的(我离我想要的地方还很远,但是你不必担心这个。):
此时应用程序应该执行以下操作:
1) 在MainActivity中:
a) 创建一个包含 3 个实例的数组 Parcelable 接口(class VocCard 实现 Parcelable),VocCard[] voc1,在这种情况下。由于 class VocCard 实现了 Parcelable,一个 3个实例的构建获得包裹
- b) 创建一个名为 vocCardList 的 VocCard 类型的 ArrayList 并添加 voc1 的所有 3 个元素到 vocCardList。
- c) 创建一个开始按钮的实例,它为 单击时启动第二个 activity 称为 PracticeActivity。
- d) 将带有 Parcelable 的 ArrayList vocCardList 添加到 意图。
2) 在 PracticeActivity
- a) 获取 MainActivity 创建的意图。
- b) 从 intent 中检索 ArrayList vocCardList
- c) 获取vocCardsList的任意元素并赋值一个类型的变量 VocCard 给它。
- d) 通过调用 Voccard 实例检索分配的 Voccard 实例的值 方法。
- e) 通过将 TextView 设置为值的字符串来显示该值 值。
- f) 创建一个 Button nextButton,它创建一个开始的意图 第二个 activity PracticeActivity 再次作为某种递归。
- g) 添加 ArrayList vocCardList with parcelable 到 intent。
- h) 重复 2) a)-g) 直到 App 被 closing-icon 关闭。
我目前停留在 2) c),因为该应用程序只能按照上述索引 0 的方式工作。只有 VocCard card0 = vocCardList1.get( 0);有效,vocCardList1.get(1),或 vocCardList1.get(2);不要,尽管 1 和 2 在 ArrayList 边界内。
奇怪的是,使用索引 1 和索引 2 的运行时异常消息不一样:
与 vocCardList1.get(1):java.lang.ClassCastException: java.lang.String cannot be cast to com.undiclosed.smartcards.VocCard
与 vocCardList1.get(2):java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.undisclosed.smartcards.VocCard.returnVocForeign()' on a null object reference
问题:
为什么我不能按照预期的方式访问 ArrayList 的元素?当我在网上搜索时,我可能在寻找错误的东西。
MainActivity.java:
package com.undisclosed123.smartcards;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<VocCard> vocCardList;
private String[] voc_f = {"bread","apple","water"};
private String[] voc_n = {"pain","pomme","eau"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Create VocCards and add to List
vocCardList = new ArrayList<VocCard>();
VocCard[] voc1 = new VocCard[3];
Parcel in = Parcel.obtain();
for(int i = 0; i < 3; i++){
voc1[i] = new VocCard(in);
voc1[i].setVocForeign(voc_f[i]);
voc1[i].setVocNative(voc_n[i]);
vocCardList.add(voc1[i]);
}
// Create Intent and assign the parcelable List for sending to second activity on btn click
Button startBtn = (Button) findViewById(R.id.button);
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
@SuppressWarnings("unchecked")
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, PracticeActivity.class);
intent.putParcelableArrayListExtra("voc1",(ArrayList)vocCardList);
getApplicationContext().startActivity(intent);
}
});
}
}
及以下,PracticeActivity.java:
(很抱歉被注释掉的大部分内容,我想这可以帮助传达我进一步的意图 class)
package com.undisclosed123.smartcards;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
public class PracticeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice);
// Get the Intent that started this activity and extract the string
Intent intent = getIntent();
final ArrayList<VocCard> vocCardList1 = intent.getParcelableArrayListExtra("voc1"); //
//Get the Data from the VocCards
//VocCard card4count = vocCardList1.get(2);
// card4count.increaseCount();
//int count = card4count.getCount();
/* if(count >= vocCardList1.size()){
// TODO
//Create new intent for EndPracticeActivity
//makeshift statement
count--;
}*/
VocCard card0 = vocCardList1.get(2);
// VocCard card1 = vocCardList1.get(1);
String test1 = card0.returnVocForeign();
// card0.increaseCount();
// String test1 = "test1";
//Make a TextView display the transfered String
TextView textView = findViewById(R.id.textView);
textView.setText(test1);
//Create another intent that recalls same activity recursively
Button nextBtn = (Button) findViewById(R.id.button2);
nextBtn.setOnClickListener(new View.OnClickListener() {
@Override
@SuppressWarnings("unchecked")
public void onClick(View v) {
Intent intent = new Intent(PracticeActivity.this, PracticeActivity.class);
intent.putParcelableArrayListExtra("voc1",(ArrayList)vocCardList1);
getApplicationContext().startActivity(intent);
}
}); /**/
}
}
最后,VocCard.java:
package com.undisclosed123.smartcards;
import android.os.Parcel;
import android.os.Parcelable;
public class VocCard implements Parcelable {
private String voc_foreign;
private String voc_native;
private boolean learned;
private int error_level;
private static int counter;
public String returnVocForeign(){
return voc_foreign;
}
public void setVocForeign(String voc_f){
voc_foreign = voc_f;
}
public String returnVocNative(){
return voc_native;
}
public void setVocNative(String voc_n){
voc_native = voc_n;
}
public boolean checkLearned(){
return learned;
}
public int getErrorLevel(){
return error_level;
}
public void makeLearned(){
learned = true;
}
public void increaseErrorLevel(){
error_level++;
}
public int getCount(){
return counter;
}
public void increaseCount(){
counter++;
}
public VocCard(Parcel in) {
voc_foreign = in.readString();
voc_native = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(voc_foreign);
dest.writeString(voc_native);
dest.writeInt((Boolean) learned ? 1 : 0);
dest.writeInt(error_level);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<VocCard> CREATOR = new Creator<VocCard>() {
@Override
public VocCard createFromParcel(Parcel in) {
return new VocCard(in);
}
@Override
public VocCard[] newArray(int size) {
return new VocCard[size];
}
};
}
问题在于将数据写入 Parcel
并从中读取数据。
public class VocCard implements Parcelable {
...
...
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(voc_foreign);
dest.writeString(voc_native);
dest.writeInt(learned ? 1 : 0);
dest.writeInt(error_level);
}
/**
* This constructor is invoked by the method
* createFromParcel(Parcel source) of the object CREATOR.
*
* The order and number of writing and reading data to and from
* Parcel should be same
**/
private VocCard(Parcel in) {
voc_foreign = in.readString();
voc_native = in.readString();
learned = in.readInt() == 1;
error_level = in.readInt();
}
/**
* A constructor that initializes the VocCard object.
**/
VocCard(String voc_foreign, String voc_native) {
this.voc_foreign = voc_foreign;
this.voc_native = voc_native;
}
...
...
}
MainActivity
内部 onCreate
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
...
//Create VocCards and add to List
mVocCardList = new ArrayList<>(3);
for (int i = 0; i < 3; i++) {
mVocCardList.add(new VocCard(voc_f[i], voc_n[i]));
}
Button startBtn = (Button) findViewById(R.id.button);
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, PracticeActivity.class);
intent.putParcelableArrayListExtra("voc1", (ArrayList<? extends Parcelable>) mVocCardList);
startActivity(intent);
}
});
}
现在在PracticeActivity
VocCard
列表
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
...
final ArrayList<VocCard> vocCardList = getIntent().getParcelableArrayListExtra("voc1");
final VocCard card = vocCardList.get(2);
String test = card.getVocForeign();
...
...
}