简体   繁体   中英

Adding parsed JSON to a ListView and displaying it

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);

            }

        }
    }
}

The code above basically tries to parse a JSON data from https://api.github.com/users/famous/repos , adds some certain info (repo name, id, description) to the corresponding lists, and tries to display that on the listView that I created.

The listView works when I hard code the information (meaning that there is no problem with the listView itself), but when I try to put in the data inside the list (which has the parsed JSON info and I tested that it is actually inside the list), it gives me an empty list.

How can I make this work?

The data come asynchronous so inside onCreateView() the list data may not be ready yet for adding to adapter.

You need to move the code that add elements to ListView adapter into onPostExecute() , after formatJSONArray() method, then call notifyDatasetChange() to invalidate the 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();
           }
  }
for(int i = 0; i < repoNameList.size(); i++) {
     repoListItems.add(new RepositoryItem(i,repoNameList.get(i),userNameList.get(i), "ddd"));
}
adapter.notifyDataSetChanged();

` add this line before

}catch (JSONException jsonException){

You can call adapter.notifiDatasetchange() in your formatJSONArray method:

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){

        }
    }

If it don't work , you can set adapter again in your formatJSONArray method

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

It worked for me. I hope it can help your problem!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM