Android Custom ListView没有与Volley一起构建

问题描述 投票:1回答:2

我正在从公共源解析JSON数组并将它们插入到自定义ListView中。我有4节课;

  1. MySingleton for Volley Requests 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; }}
  2. GameListItem 公共类GameListItem { 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; }}
  3. CustomListAdapter 公共类CustomListAdapter扩展BaseAdapter { 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; }}
  4. 主要活动 公共类MainActivity扩展AppCompatActivity { 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也打印出来(在解析器里面)

谢谢!

java android json listview android-volley
2个回答
1
投票

如果请求成功,则必须将数据更改通知适配器。在你的情况下,adapter.notifyDataSetChanged();在catchRedponse里面的catch块之前。


1
投票

requestQueue.stop语句后添加以下行:

adapter.notifyDataSetChanged();

首先,当您设置适配器时,列表没有数据,因为Volley请求将异步进行,这就是为什么您需要让适配器知道其数据何时发生更改。

来自the documentation

notifyDataSetChanged()

通知附加的观察者基础数据已被更改,反映数据集的任何视图都应自行刷新。

© www.soinside.com 2019 - 2024. All rights reserved.