简体   繁体   English

通过意图在第二个活动中通过Parcelable从检索到的ArrayList中获取ArrayList的元素

[英]Get elements of ArrayList from retrieved ArrayList via intent via Parcelable in 2nd activity

I'm trying to build a simple android that should simulate learning vocabulary with cards. 我正在尝试构建一个简单的机器人,该机器人应该模拟卡片的学习词汇。 to get to the final app, I'm going to add functionality and complexity step by step, by learning new things, and adding new things. 为了进入最终的应用程序,我将通过学习新事物并添加新事物来逐步添加功能和复杂性。

I'm about to tell you where I'm stuck, but first, here's what my App should do, so far (I'm still far, far way from where I'd like it to go, but you don't have to mind about that.): 我要告诉你我被卡住的地方,但是首先,这是我的应用程序应该做的事情,到目前为止(我距离我想要去的地方还很远,但是你没有请注意。):

At this point the app should do the folowing thing: 此时,应用应执行以下操作:

  • 1) in the MainActivity: 1)在MainActivity中:

  • a) Create an Array of 3 instances of an implementation of the Parcelable interface (class VocCard implements Parcelable), VocCard[] voc1, in this case. a)在这种情况下,创建一个由Parcelable接口实现的3个实例组成的数组(类VocCard实现Parcelable),即VocCard [] voc1。 Since the class VocCard implements Parcelable, a Parcel is obtained for the construction of the 3 instances. 由于VocCard类实现了Parcelable,因此获得了用于构建3个实例的Parcel。

  • b) Create an ArrayList of the type VocCard called vocCardList and add all 3 elements of voc1 to vocCardList. b)创建一个名为vocCardList的VocCard类型的ArrayList,并将voc1的所有3个元素添加到vocCardList。
  • c) Create an instance of a start button which creates an intent for starting a 2nd activity called PracticeActivity when clicked. c)创建一个启动按钮的实例,该实例创建一个旨在在单击时启动名为PracticeActivity的第二个活动的意图。
  • d) Add the ArrayList vocCardList with Parcelable to the intent. d)将具有Parcelable的ArrayList vocCardList添加到该意图。

2) in PracticeActivity 2)实践活动

  • a) Get the intent created by MainActivity. a)获取MainActivity创建的意图。
  • b) Retrieve ArrayList vocCardList from intent b)从意图中检索ArrayList vocCardList
  • c) Get any element of vocCardsList and assign a variable of the type VocCard to it. c)获取vocCardsList的任何元素,并为其分配VocCard类型的变量。
  • d) Retrieve a value of the assigned Voccard instance by invoking its methods. d)通过调用其方法来获取分配的Voccard实例的值。
  • e) Display that value by setting a TextView to the value's String value. e)通过将TextView设置为值的String值来显示该值。
  • f) Create a Button nextButton which creates an intent for starting the 2nd activity PracticeActivity again, as some kind of recursion. f)创建一个按钮nextButton,该按钮创建某种意图以某种递归的方式再次启动第二个活动PracticeActivity。
  • g) Add the ArrayList vocCardList with parcelable to intent. g)将具有可拆分的ArrayList vocCardList添加到intent。
  • h) repeat 2) a)-g) until App is closed by closing-icon. h)重复2)a)-g),直到应用程序通过关闭图标关闭。

I'm currently stuck at 2) c) , insofar that the App only works as described above for the index 0. Only VocCard card0 = vocCardList1.get(0); 我目前停留在2)c)的范围内 ,因为该应用程序只能按上述索引0的方式工作。仅VocCard card0 = vocCardList1.get(0); works, vocCardList1.get(1), or vocCardList1.get(2); 作品,vocCardList1.get(1)或vocCardList1.get(2); don't, despite 1 and 2 being within the ArrayList boundries. 不会,尽管1和2在ArrayList边界之内。

Oddly enough, the Runtime Exeption Message for using index 1 and index 2 is not the same: 奇怪的是, 使用索引1和索引2Runtime Exeption消息并不相同:

with vocCardList1.get(1): java.lang.ClassCastException: java.lang.String cannot be cast to com.undiclosed.smartcards.VocCard 使用vocCardList1.get(1): java.lang.ClassCastException: java.lang.String cannot be cast to com.undiclosed.smartcards.VocCard

with vocCardList1.get(2): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.undisclosed.smartcards.VocCard.returnVocForeign()' on a null object reference 与vocCardList1.get(2): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.undisclosed.smartcards.VocCard.returnVocForeign()' on a null object reference

Question: 题:

Why can't I acces the elements of the ArrayList the way I expected? 为什么我不能按我期望的方式访问ArrayList的元素? When I searched the web I was probably looking for the wrong stuff. 当我在网上搜索时,我可能正在寻找错误的内容。

MainActivity.java: 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);
             }
        });
    }
}

And below, PracticeActivity.java: 下面是PracticeActivity.java:

(Sorry for the large sections which are commented out, I figured it could help communicating my further intentions for that 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);
            }
        }); /**/

    }
}

And at last, VocCard.java: 最后,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];
        }
    };
}

The problem is with writing data to Parcel and reading data from it. 问题在于将数据写入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;
    }

    ...
    ...

}

Few changes in MainActivity inside onCreate onCreateMainActivity一些更改

@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);
        }
    });
}

Now get the VocCard list in PracticeActivity 现在在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();

    ... 
    ...

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM