在第二个活动中通过Parcelable通过intent获取ArrayList中的ArrayList元素

时间:2018-05-08 18:52:31

标签: java android arraylist parcelable

我正在尝试构建一个简单的机器人,应该用卡模拟学习词汇。为了进入最终的应用程序,我将逐步添加功能和复杂性,学习新东西,添加新东西。

我准备告诉你我被困在哪里,但首先,这是我的应用程序应该做的事情,到目前为止(我还远远离我希望去的地方,但你不要不得不考虑到这一点。):

此时应用程序应该执行以下操作:

  • 1)在MainActivity中:

  • a)创建一个由3个实现实例组成的数组 Parcelable接口(类VocCard实现Parcelable),VocCard [] 在这种情况下,voc1。由于VocCard类实现了Parcelable,a 获得包裹用于构建3个实例。

  • b)创建一个名为vocCardList的VocCard类型的ArrayList并添加 voc1到vocCardList的所有3个元素。
  • c)创建一个创建意图的开始按钮的实例 单击时启动名为PracticeActivity的第二个活动。
  • d)将带有Parcelable的ArrayList vocCardList添加到 意图。

2)在PracticeActivity

  • a)获取MainActivity创建的意图。
  • b)从意图
  • 中检索ArrayList vocCardList
  • c)获取vocCardsList的任何元素并分配该类型的变量 VocCard吧。
  • d)通过调用它来检索指定的Voccard实例的值 方法。
  • e)通过将TextView设置为值的String来显示该值 值。
  • f)创建一个按钮nextButton,它创建一个启动意图 第二个活动练习活动再次,作为某种递归。
  • g)将具有parcelable的ArrayList vocCardList添加到intent。
  • h)重复2)a)-g)直到App被关闭图标关闭。

我目前停留在2)c),因为App只能按照上面对索引0所述的方式工作。只有VocCard card0 = vocCardList1.get(0); works,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);
             }
        });
    }
}

以下,练习活动.java:

(很抱歉,大部分内容已被注释掉,我认为这有助于传达我对该课程的进一步意图)

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];
        }
    };
}

1 个答案:

答案 0 :(得分:0)

问题在于将数据写入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);
        }
    });
}

现在获取VocCard

中的PracticeActivity列表
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {

    ...
    ...

    final ArrayList<VocCard> vocCardList = getIntent().getParcelableArrayListExtra("voc1");

    final VocCard card = vocCardList.get(2);
    String test = card.getVocForeign();

    ... 
    ...

}