将解析的 JSONArray 加载到 recyclerView
Posted
技术标签:
【中文标题】将解析的 JSONArray 加载到 recyclerView【英文标题】:Loading parsed JSONArray into a recyclerView 【发布时间】:2020-09-10 14:49:48 【问题描述】:我正在尝试将 API 调用的结果加载到 recyclerView 中。我创建了一个数据模型来保存要用于填充 recyclerView 适配器的结果数组(字符串)。但是一旦解析了 JSON 文件,应用程序会在调用数据模型的“setValues”时崩溃,但结果会准确地显示在 logcat 上。 我的代码如下:
MainActivity
package com.limitless.googlebooks;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.NetworkInterface;
import java.util.ArrayList;
import static android.text.TextUtils.isEmpty;
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String>
private EditText bookImput;
private RecyclerView recyclerView;
private ProgressBar progressBar;
private static Books books;
ArrayList<Books> booksArray;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bookImput = findViewById(R.id.bookInput);
progressBar = findViewById(R.id.progressBar);
recyclerView = findViewById(R.id.bookRecyclerView);
booksArray = new ArrayList<>();
BooksAdapter adapter = new BooksAdapter(booksArray);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
if(LoaderManager.getInstance(this).getLoader(0) != null)
LoaderManager.getInstance(this).initLoader(0,null, this);
public void searchBooks(View view)
String queryText = bookImput.getText().toString();
InputMethodManager methodManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
if(methodManager != null)
methodManager.hideSoftInputFromWindow(view.getWindowToken(),
methodManager.HIDE_NOT_ALWAYS);
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = null;
if(connectivityManager != null)
networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo != null && !isEmpty(queryText) && networkInfo.isConnected())
Bundle queryBundle = new Bundle();
queryBundle.putString("queryString", queryText);
LoaderManager.getInstance(this).restartLoader(0, queryBundle, this);
progressBar.setVisibility(View.VISIBLE);
else
if(isEmpty(queryText))
Toast.makeText(this, R.string.emptyquery, Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, R.string.no_internet, Toast.LENGTH_SHORT).show();
@NonNull
@Override
public Loader<String> onCreateLoader(int id, @Nullable Bundle args)
String queryString = "";
if(args != null)
queryString = args.getString("queryString");
return new BookLoader(this, queryString);
@Override
public void onLoadFinished(@NonNull Loader<String> loader, String data)
try
JSONObject jsonObject = new JSONObject(data);
JSONArray itemsArray = jsonObject.getJSONArray("items");
int i = 0;
String title = null;
String authors = null;
String publisher = null;
String date = null;
while(i < itemsArray.length() && title == null && authors == null && date == null)
JSONObject book = itemsArray.getJSONObject(i);
JSONObject volumeInfo = book.getJSONObject("volumeInfo");
try
title = volumeInfo.getString("title");
authors = volumeInfo.getString("authors");
publisher = volumeInfo.getString("publisher");
date = volumeInfo.getString("publishedDate");
catch (JSONException e)
e.printStackTrace();
i++;
if(title != null && authors != null && date != null)
books.setBookName(title);
books.setAuthorsName(authors);
books.setPublisher(publisher);
books.setPublishedDate(date);
booksArray.add(books);
else
books.setBookName(String.valueOf(R.string.no_results));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");;
catch (JSONException e)
books.setBookName(String.valueOf(R.string.error));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");
e.printStackTrace();
@Override
public void onLoaderReset(@NonNull Loader<String> loader)
数据模型
package com.limitless.googlebooks;
public class Books
private String bookName;
private String authorsName;
private String publisher;
private String publishedDate;
public Books(String bookName, String authorsName, String publisher, String publishedDate)
this.bookName = bookName;
this.authorsName = authorsName;
this.publisher = publisher;
this.publishedDate = publishedDate;
public Books()
public String getBookName()
return bookName;
public void setBookName(String bookName)
this.bookName = bookName;
public String getAuthorsName()
return authorsName;
public void setAuthorsName(String authorsName)
this.authorsName = authorsName;
public String getPublisher()
return publisher;
public void setPublisher(String publisher)
this.publisher = publisher;
public String getPublishedDate()
return publishedDate;
public void setPublishedDate(String publishedDate)
this.publishedDate = publishedDate;
适配器类
package com.limitless.googlebooks;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class BooksAdapter extends RecyclerView.Adapter<BooksAdapter.BooksHolder>
ArrayList<Books> booksArrayList;
public BooksAdapter(ArrayList<Books> booksArray)
this.booksArrayList = booksArray;
@NonNull
@Override
public BooksHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
Context context = parent.getContext();
View itemView = LayoutInflater.from(context).inflate(R.layout.booklist, parent, false);
return new BooksHolder(itemView);
@Override
public void onBindViewHolder(@NonNull BooksHolder holder, int position)
Books books = booksArrayList.get(position);
holder.bind(books);
@Override
public int getItemCount()
return booksArrayList.size();
public class BooksHolder extends RecyclerView.ViewHolder
private TextView bookName;
private TextView authorsName;
private TextView publisher;
private TextView publishedDate;
public BooksHolder(@NonNull View itemView)
super(itemView);
bookName = itemView.findViewById(R.id.bookTitle);
authorsName = itemView.findViewById(R.id.authorsName);
publisher = itemView.findViewById(R.id.publisher);
publishedDate = itemView.findViewById(R.id.publishedDate);
public void bind(Books books)
bookName.setText(books.getBookName());
authorsName.setText(books.getAuthorsName());
publisher.setText(books.getPublisher());
publishedDate.setText(books.getPublishedDate());
【问题讨论】:
你能把你得到的错误贴在日志上吗? 你能从 logcat 打印错误吗?这将有助于我们正确理解根本原因。 【参考方案1】:在你的MainActivity
:
这些
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String>
....
private static Books books;
ArrayList<Books> booksArray;
变成:
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String>
....
private Books books;
private ArrayList<Books> booksArray;
private BooksAdapter adapter;
在onCreate()
:
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
........
adapter = new BooksAdapter(booksArray);
........
........
现在在onLoadFinished()
:
这个:
if(title != null && authors != null && date != null)
books.setBookName(title);
books.setAuthorsName(authors);
books.setPublisher(publisher);
books.setPublishedDate(date);
booksArray.add(books);
else
books.setBookName(String.valueOf(R.string.no_results));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");;
catch (JSONException e)
books.setBookName(String.valueOf(R.string.error));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");
e.printStackTrace();
变成:
if(title != null && authors != null && date != null)
books = new Books(title,authors,publisher,date);
booksArray.add(books);
adapter.notifyDataSetChanged();
else
books = new Books(String.valueOf(R.string.no_results),"","","");
//if you want to add them to array add them, if not then don't
booksArray.add(books);
adapter.notifyDataSetChanged();
catch (JSONException e)
books = new Books(String.valueOf(R.string.error),"","","");
//if you want to add them to array add them, if not then don't
booksArray.add(books);
adapter.notifyDataSetChanged();
e.printStackTrace();
【讨论】:
谢谢。我注意到我没有在 onCreate 中实例化 Books 对象。但是您的回答帮助我解决了另一个难题。我很感激 如果这有助于接受答案,以便其他有同样问题的人知道这是一个解决方案。祝你好运。以上是关于将解析的 JSONArray 加载到 recyclerView的主要内容,如果未能解决你的问题,请参考以下文章
使用 SwiftyJSON 将 JSONArray 解析为字符串数组
JSONJSONObject 与 JSONArray 详细介绍及其应用方式