我正在从公共源解析JSON数组并将它们插入到自定义ListView中。我有4节课;
public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;
private MySingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
mImageLoader = new ImageLoader(mRequestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized MySingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new MySingleton(context);
}
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return mImageLoader;
}}
private String itemName, itemLongDescription, itemShortDescription, itemReleaseDate;
String releaseyear;
private int iconID, imageID;
public GameListItem(String itemName, String releaseyear, int iconID) {
this.itemName = itemName;
this.releaseyear = releaseyear;
this.iconID = iconID;
}
public String getItemName() {
return itemName;
}
public String getReleaseyear() {
return releaseyear;
}}
private Context mContext;
private LayoutInflater mInflater;
private List<GameListItem> mDataSource;
public CustomListAdapter(Context context, List<GameListItem> items) {
mContext = context;
mDataSource = items;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mDataSource.size();
}
@Override
public Object getItem(int position) {
return mDataSource.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = mInflater.inflate(R.layout.gamelist_layout, parent, false);
TextView titleTextView = (TextView) rowView.findViewById(R.id.gameTitle);
TextView subtitleTextView = (TextView) rowView.findViewById(R.id.gameDescription);
titleTextView.setText(mDataSource.get(position).getItemName());
subtitleTextView.setText(mDataSource.get(position).getReleaseyear());
return rowView;
}}
final String TAG = this.getClass().getSimpleName();
RequestQueue requestQueue;
private CustomListAdapter adapter;
private List<GameListItem> gameList;
private GameListItem gameItem;
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Cache cache = new DiskBasedCache(getCacheDir(), 1024*1024);
Network network = new BasicNetwork(new HurlStack());
requestQueue = new RequestQueue(cache, network);
requestQueue.start();
listView = (ListView) findViewById(R.id.gameListView);
gameList = new ArrayList<>();
//This works and gives me a ListView with 5 rows
gameList.add(new GameListItem("Test 1", "2019", R.mipmap.ic_launcher));
gameList.add(new GameListItem("Test 2", "2092", R.mipmap.ic_launcher));
gameList.add(new GameListItem("Test 3", "3243", R.mipmap.ic_launcher));
gameList.add(new GameListItem("Test 4", "2323", R.mipmap.ic_launcher));
gameList.add(new GameListItem("Test 5", "2123", R.mipmap.ic_launcher));
//This doesn't work...
String url = "http://api.androidhive.info/json/movies.json";
JsonArrayRequest stringRequest = new JsonArrayRequest(url, new Response
.Listener<JSONArray>(){
@Override
public void onResponse(JSONArray jsonArray) {
if (jsonArray == null) {
Toast.makeText(MainActivity.this, "jsonArray is Null", Toast.LENGTH_LONG).show();
} else {
try {
Toast.makeText(MainActivity.this, "ATTEMPTING PARSING", Toast.LENGTH_SHORT).show();
Log.e("This is the json array", jsonArray.toString());
for (int i = 0; i < jsonArray.length(); i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String title = jsonObject.getString("title");
int releaseYear = jsonObject.getInt("releaseYear");
gameList.add(new GameListItem(releaseDate, "" + releaseYear , R.mipmap.ic_launcher));
//this prints all the Titles and Release Dates correctly
Log.e("This is a title", title);
Log.e("This is a year", "HERE " + releaseYear);
}
} catch(JSONException e){
Log.i("JSON exception", e.toString());
Toast.makeText(MainActivity.this, "JSON ERROR", Toast.LENGTH_LONG).show();
}
requestQueue.stop();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("This is an error", ""+error.getMessage()+","+error.toString());
}
});
MySingleton.getInstance(this).addToRequestQueue(stringRequest);
adapter = new CustomListAdapter(this, gameList);
listView.setAdapter(adapter);
}}
正如在主活动中所评论的,当我手动添加一行(带有手动数据)时,ListView构建并显示,但解析器没有显示任何内容。我检查了无数的教程,一切看起来都井然有序,我甚至看了看这里,并按照大部分回答我发现什么都没有。有人可以看到导致列表不能构建/打印的错误吗?
PS。 Log.e也打印出来(在解析器里面)
谢谢!
如果请求成功,则必须将数据更改通知适配器。在你的情况下,adapter.notifyDataSetChanged();在catchRedponse里面的catch块之前。
在requestQueue.stop
语句后添加以下行:
adapter.notifyDataSetChanged();
首先,当您设置适配器时,列表没有数据,因为Volley请求将异步进行,这就是为什么您需要让适配器知道其数据何时发生更改。
notifyDataSetChanged()
通知附加的观察者基础数据已被更改,反映数据集的任何视图都应自行刷新。