java - Android 自定义 ListView 不使用 Volley 构建

标签 java android json listview android-volley

我正在解析来自公共(public)源的 JSON 数组并将它们插入到自定义 ListView 中。我有 4 个类(class);

  1. 用于 Volley 请求的 MySingleton

    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. 游戏列表项

    公共(public)类 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. 自定义列表适配器

    公共(public)类 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. 主要 Activity

    公共(public)类 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);
    
    
    }}
    

如主要 Activity 中所述,当我手动添加一行(使用手动数据)时,ListView 会构建并显示,但解析器未显示任何内容。 我检查了无数教程,一切似乎都井井有条,我什至在这里查看并遵循了大部分答案,但我一无所获。 有人可以看到导致列表无法构建/打印的错误吗?

附言。 Log.e 也打印(在解析器内部)

谢谢!

最佳答案

如果请求成功,你必须通知适配器数据变化。在你的情况下 adapter.notifyDataSetChanged();在 onResponse 中的 catch block 之前。

关于java - Android 自定义 ListView 不使用 Volley 构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38277433/

相关文章:

java - 通过套接字将 String 和 Byte[] 从 Android 应用程序发送到 Python 服务器

安卓电池分析。计算电池循环

java - 如何编写必要的 java 类以对以下 json 对象使用 gson.fromJson() ?

json - Jackson @JsonFormat 设置日期少一天

java - 使用 SonarQube Scanner 分析 java 代码时出错

java - 将 CTRL-SHIFT-A-D 封装在 java 字符串中

java - 如何区分没有互联网连接时抛出的异常与没有可用服务器/或错误 URL 的情况?

java - 为什么我在关闭 GDX 游戏窗口后会收到错误消息?

android - 如何在 Android 的 EditText View 中添加图标?

python - 将字符串添加到 python 列表 -> json 对象