【问题标题】:Can't correctly pass data through Intent from ListView无法从 ListView 通过 Intent 正确传递数据
【发布时间】:2018-10-19 18:16:21
【问题描述】:

我尝试将我在ListView 中选择的数据项传递给下一个Activity。但我所能做的就是第二个活动是空的或nullpoinexception 错误。我用RecycleView 做的,但是ListView 有一些问题。

主要活动:

public class ListViewPlaces extends AppCompatActivity {

FirebaseFirestore mFirestore = FirebaseFirestore.getInstance();
CollectionReference placeRef = mFirestore.collection("Places");
Query query;
ListView mListView;
String name;
Places places;
ArrayList<Places> randomPlaceList;
PlaceAdapter mAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_view_places);
    mListView = findViewById(R.id.place_list);

    randomPlaceList = new ArrayList<>();

    Boolean l_check1 = getIntent().getExtras().getBoolean("1");
    Boolean l_check2 = getIntent().getExtras().getBoolean("2");

    if (l_check2){
        query = placeRef.whereEqualTo("colour", "red");
    } else if (l_check1){
        query = placeRef.whereEqualTo("size", "1");
    } else {
        query = placeRef.whereEqualTo("size", "2");
    }
        query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    List<Places> placesList = new ArrayList<>();
                    for (DocumentSnapshot document : task.getResult()) {
                        Places place = document.toObject(Places.class);
                        placesList.add(place);
                    }
                    int placeCount = placesList.size();
                    Random randomGenerator = new Random();
                    ArrayList<Places> randomPlaceList = new ArrayList<>();
                    for (int i = 1; i <= 3; i++) {
                        randomPlaceList.add(placesList.get(randomGenerator.nextInt(placeCount)));
                    }
                    ListView mListView = (ListView) findViewById(R.id.place_list);
                    mAdapter = new PlaceAdapter(randomPlaceList, getBaseContext());
                    mListView.setAdapter(mAdapter);
                }
            }
        });


        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Places places = mAdapter.getItem(position);
                Intent intent = new Intent(getApplicationContext(), Card_activity.class);
                intent.putExtra("name", places.getName());
                startActivity(intent);
            }
        });

    }
}

我的模型课:

public class Places {
private String image, name;

public Places() {

}

public Places(String image, String name) {
    this.image = image;
    this.name = name;
}

public String getImage() { return image; }
public String getName() { return name; }
}

自定义适配器:

class PlaceAdapter extends ArrayAdapter<Places> {

private ArrayList<Places> dataSet;
Context mContext;

private static class ViewHolder {
    TextView name_text;
    ImageView image_text;
}

public PlaceAdapter(ArrayList<Places> dataSet, Context context ) {
    super(context, R.layout.item_list, dataSet);

    this.dataSet = dataSet;
    this.mContext = context;

}

@Override
public View getView(int position, View converView, ViewGroup parent) {

    Places places = getItem(position);
    ViewHolder viewHolder;

    final View result;

    if (converView == null) {
        viewHolder = new ViewHolder();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        converView = inflater.inflate(R.layout.item_list, parent, false);
        viewHolder.name_text = (TextView) converView.findViewById(R.id.text_image_id);
        viewHolder.image_text = (ImageView) converView.findViewById(R.id.image_id);

        result = converView;

        converView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) converView.getTag();
        result = converView;
    }

    viewHolder.name_text.setText(places.getName());
    Glide.with(getContext()).load(places.getImage()).into(viewHolder.image_text);

    return converView;

第二个活动,我传递数据的地方:

public class Card_activity extends AppCompatActivity implements View.OnClickListener{

    TextView mTextView;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.massive_places);

        mTextView = findViewById(R.id.head_name);
        String name = getIntent().getStringExtras("name")
        mTextView.setText(name);
}
}

已编辑:错误

java.lang.NullPointerException:尝试调用虚拟方法 空对象上的“java.lang.Object java.util.ArrayList.get(int)” 参考

在这一行:

Places places = randomPlaceList.get(position);

错误:

进程:com.example.eugene.lafinalproduction,PID:8352 java.lang.IllegalArgumentException: n

这一行的问题:

randomPlaceList.add(placesList.get(randomGenerator.nextInt(placeCount)));

【问题讨论】:

  • 错误在哪里抛出?还添加错误堆栈跟踪
  • 已添加。@PierGiorgioMisley
  • 哪一行抛出 NPE?
  • 在问题底部添加@Code-Apprentice

标签: java android firebase listview android-intent


【解决方案1】:

该错误意味着您的randomPlaceList 为空。

由于我看不到应用程序或您为得到错误而执行的逻辑,所以我只是根据我看到的内容进行。

第一件事是,如果您需要获取点击的项目,应该通过调用adaptergetItem(position) 方法来完成;你可以像下面这样轻松地实现它:

@Override
public Places getItem(int position) {
    if(dataSet != null && position < dataSet.size()){
       return dataSet.get(position);
    }
    return null;
}

现在您可以从您的activity 执行如下调用:

Places places = mAdapter.getItem(position);

记得在初始化 adapter 时添加对它的引用,方法是在活动变量中添加 PlaceAdapter mAdapter; 并将初始化替换为

mAdapter = new PlaceAdapter(randomPlaceList, getBaseContext());
mListView.setAdapter(mAdapter);  

快速阅读代码,我对此也没有多大意义:

this.randomPlaceList = randomPlaceList;

但也许你删掉了一些代码,但我更愿意向你报告,以防万一:)


注意指明错误

错误在这里,它是关于变量引用:

        query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    List<Places> placesList = new ArrayList<>();
                    for (DocumentSnapshot document : task.getResult()) {
                        Places place = document.toObject(Places.class);
                        placesList.add(place);
                    }                      
                    int placeCount = placesList.size();
                    Random randomGenerator = new Random();  

                    // In the line below, you specify a new ArrayList that is LOCAL, you don't refer to the Activity's object
                    ArrayList<Places> randomPlaceList = new ArrayList<>();
                    for (int i = 1; i <= 3; i++) {
                        randomPlaceList.add(placesList.get(randomGenerator.nextInt(placeCount)));
                    }
                    ListView mListView = (ListView) findViewById(R.id.place_list);
                    PlaceAdapter placeAdapter = new PlaceAdapter(randomPlaceList, getBaseContext());
                    mListView.setAdapter(placeAdapter);                    
            }
        });

您应该将其替换为:

        query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    List<Places> placesList = new ArrayList<>();
                    for (DocumentSnapshot document : task.getResult()) {
                        Places place = document.toObject(Places.class);
                        placesList.add(place);
                    }                      
                    int placeCount = placesList.size();
                    Random randomGenerator = new Random();

                    randomPlaceList = new ArrayList<>(); //this is the activity's list
                    for (int i = 1; i <= 3; i++) {
                        randomPlaceList.add(placesList.get(randomGenerator.nextInt(placeCount)));
                    }
                    ListView mListView = (ListView) findViewById(R.id.place_list);
                    PlaceAdapter placeAdapter = new PlaceAdapter(randomPlaceList, getBaseContext());
                    mListView.setAdapter(placeAdapter);                    
            }
        });

否则活动的列表将永远为空,因为你从来没有初始化它

希望对你有帮助

【讨论】:

  • 我使用了你答案的第一部分,它有帮助,答案的第二部分使OnItemClickListener方法全部变红,所以我没有用你说的local refer替换行。@Pier乔治·米斯利
  • 我编辑了一个 Main Activity 类,现在可以使用了。@Pier Giorgio Misley
  • 非常感谢,你帮了我很多忙!@Pier Giorgio Misley
  • @SpikeJohnson 很高兴它帮助了你!如果您有更多问题,我/我们在这里 :)
  • @SpikeJohnson 是的,我写它只是为了更好地说明错误的原因,但第一种方法可能更好^^
【解决方案2】:

ListViewPlacesonCreate 方法中初始化您的randomPlaceList

randomPlaceList = new ArrayList<>();

目前您正在以这种方式初始化您的randomPlaceList this.randomPlaceList = randomPlaceList; 这是错误的,因为您正在分配 randomPlaceList 的相同副本,就像 a = a

并删除 ArrayList&lt;Places&gt; randomPlaceList = new ArrayList&lt;&gt;(); 内部的局部变量 query.get().addOnCompleteListener();

getIntent().getExtras() 返回一个 Bundle,它的值是 Key-Value 对(您可以将 Key-Value 对的多个值添加到 Bundle),但是您没有传递Bundle,你只是传递了一对Key-Value。所以最好在你的Card_activity中调用getStringExtra("name")

String name = getIntent().getStringExtra("name");

代替

String name = getIntent().getExtras().getString("name");

【讨论】:

  • 一直以来都是错误,早在 RecycleView 中都使用 .getExtras.getString。我有问题。@Ghulam Moinul Quadir
  • @SpikeJohnson 我已经更新了我的答案。我认为这可能会有所帮助
  • 同一个地方出现同样的错误@Ghulam Moinul Quadir
【解决方案3】:

在你的第二个活动中,改变这个:

String name = getIntent().getExtras().getString("name");

收件人:

String name = getIntent().getStringExtra("name");

【讨论】:

  • 这是一直以来的错误,在 RecycleView 的早期,都使用 .getExtras.getString。我提出了错误。@Lucas Arrefelt
  • 虽然第二个可能是首选,但它只是第一个的简写。这两行代码做的事情完全相同,不会修复错误。
【解决方案4】:

您的代码中有几个问题。但是,让我们只关注您的问题。 你应该使用

intent.getStringExtra 

从以前的活动中获取字符串数据,而不是使用

intent.getExtras().getString("name");

getStringExtra 和 getExtras 是不同的。

【讨论】:

  • 一直以来都是错误,在 RecycleView 的早期,所有都与 .getExtras.getString 一起工作。我提出了错误。@Chauyan
  • 两者都做同样的事情。
  • 我认为对于那个异常,你应该是 randomPlaceList 是否为空,如果这个变量不为空,你应该再次检查它的大小以避免索引超出边界异常@SpikeJohnson
猜你喜欢
  • 1970-01-01
  • 2016-01-20
  • 1970-01-01
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
  • 2011-07-19
相关资源
最近更新 更多