【问题标题】:Adding parsed JSON to a ListView and displaying it将解析的 JSON 添加到 ListView 并显示它
【发布时间】:2017-10-23 07:55:02
【问题描述】:
public class GithubTab extends Fragment implements AdapterView.OnItemClickListener {

    ListView repoListView;

    private ListAdapter adapter;
    private List<RepositoryItem> repoListItems;

    private List<String> repoNameList;
    private List<String> userNameList;
    private List<String> descriptionList;

    private TextView tvData;

    private static final String TAG = "Github Tab";

    Button buttonHit;
    TextView resultText;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.github_tab, container, false);

        repoListView = (ListView) view.findViewById(R.id.repoList);

        repoListItems = new ArrayList<>();
        repoNameList = new ArrayList<>();
        userNameList = new ArrayList<>();
        descriptionList = new ArrayList<>();

        adapter = new ListAdapter(getContext(), repoListItems);
        repoListView.setAdapter(adapter);
        tvData = (TextView) view.findViewById(R.id.tvJsonItem);

        // Clickable: able to open the GitHub webpage of the re

        repoListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(getContext(), "Clicked id" + view.getTag(), Toast.LENGTH_SHORT).show();
            }
        });

        new JSONTask().execute("https://api.github.com/users/whyjay17/repos");

        for(int i = 0; i < repoNameList.size(); i++) {
            repoListItems.add(new RepositoryItem(i, repoNameList.get(i), userNameList.get(i), "ddd"));
        }

        return view;

    }

    public class JSONTask extends AsyncTask<String, String, String> {
        @Override

        // Any non-UI thread process is running in this method. After completion, it sends the result to OnPostExecute
        protected String doInBackground(String... params) {

            HttpURLConnection connection = null;
            BufferedReader reader = null;

            try {

                .... Code Hidden ....

                return retreivedJson;

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //cant close null

                if (connection != null) {
                    // close both connection and the reader
                    connection.disconnect();
                }
                try {
                    if (reader != null) {
                        reader.close();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return null;

        }


        public void formatJSONArray(String results){
            try {
                JSONArray jsonArray = new JSONArray(results);
                for(int i = 0; i < jsonArray.length(); i++){
                    JSONObject jsonObject=jsonArray.getJSONObject(i);
                    if(jsonObject.optString("name") != null) {
                        //tvData.append(jsonObject.getString("name"));
                        repoNameList.add(jsonObject.getString("name"));

                        //Toast.makeText(getContext(), "1 " + repoNameList.get(1), Toast.LENGTH_SHORT).show();
                    }

                    if(jsonObject.optJSONObject("owner") != null){
                        JSONObject ownerObject=jsonObject.getJSONObject("owner");

                        if(ownerObject.optString("login")!=null) {
                            //tvData.append(ownerObject.getString("login"));
                            userNameList.add(ownerObject.getString("login"));
                            //ownerObject.append(ownerObject.getString("avatar_url"));
                        }
                    }
                }


            }catch (JSONException jsonException){

            }
        }

        /*
        * Called after the background computation finishes. Result of doInBackground is passed in as a parameter.
        *
        * */
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

       /* for JSONArray data*/
            if(result!=null && !result.isEmpty()) {
                formatJSONArray(result);

            }

        }
    }
}

上面的代码基本上试图解析来自https://api.github.com/users/famous/repos 的 JSON 数据,将一些特定信息(repo 名称、id、描述)添加到相应的列表中,并尝试在我创建的 listView 上显示这些信息。

当我对信息进行硬编码时(意味着 listView 本身没有问题),listView 工作,但是当我尝试将数据放入列表中时(其中包含解析的 JSON 信息,我测试它是实际上在列表中),它给了我一个空列表。

我怎样才能做到这一点?

【问题讨论】:

  • 添加新元素后,您是否为您的适配器调用了notifyDataSetChanged()

标签: android json listview


【解决方案1】:

数据是异步的,所以在onCreateView() 内部,列表数据可能还没有准备好添加到适配器。

您需要将向ListView适配器添加元素的代码移动到onPostExecute(),在formatJSONArray()方法之后,然后调用notifyDatasetChange()使ListView失效

@Override
  protected void onPostExecute(String result) {
           super.onPostExecute(result);

            /* for JSONArray data*/
            if(result!=null && !result.isEmpty()) {
                formatJSONArray(result);
                for(int i = 0; i < repoNameList.size(); i++) {
                    repoListItems.add(new RepositoryItem(i, 
                    repoNameList.get(i), userNameList.get(i), "ddd"));
                }

                adapter.notifyDatasetChanged();
           }
  }

【讨论】:

    【解决方案2】:

    您可以在 formatJSONArray 方法中调用 adapter.notifiDatasetchange():

    public void formatJSONArray(String results){
            try {
                JSONArray jsonArray = new JSONArray(results);
                for(int i = 0; i < jsonArray.length(); i++){
                    JSONObject jsonObject=jsonArray.getJSONObject(i);
                    if(jsonObject.optString("name") != null) {
                        //tvData.append(jsonObject.getString("name"));
                        repoNameList.add(jsonObject.getString("name"));
    
                        //Toast.makeText(getContext(), "1 " + repoNameList.get(1), Toast.LENGTH_SHORT).show();
                    }
    
                    if(jsonObject.optJSONObject("owner") != null){
                        JSONObject ownerObject=jsonObject.getJSONObject("owner");
    
                        if(ownerObject.optString("login")!=null) {
                            //tvData.append(ownerObject.getString("login"));
                            userNameList.add(ownerObject.getString("login"));
                            //ownerObject.append(ownerObject.getString("avatar_url"));
                        }
                    }
                }
            adapter.notifiDatasetchange();
    
            }catch (JSONException jsonException){
    
            }
        }
    

    如果不起作用,您可以在 formatJSONArray 方法中再次设置适配器

    adapter = new ListAdapter(getContext(), repoListItems);
    repoListView.setAdapter(adapter);
    

    它对我有用。希望对您的问题有所帮助!

    【讨论】:

      【解决方案3】:
      for(int i = 0; i < repoNameList.size(); i++) {
           repoListItems.add(new RepositoryItem(i,repoNameList.get(i),userNameList.get(i), "ddd"));
      }
      adapter.notifyDataSetChanged();
      

      ` 在前面添加这一行

      }catch (JSONException jsonException){
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-27
        • 1970-01-01
        • 1970-01-01
        • 2010-10-07
        • 1970-01-01
        相关资源
        最近更新 更多