Search code examples
androidandroid-fragmentsandroid-asynctaskandroid-listfragment

ListFragment with Asynctask and Custom Adapter


My problem is very basic, however I can't see the solution to it. That's my 3rd project on Android. So far I was using fragments with a ListView declared in it, onCreateView where I was inflating my ListView and onActivityCreated to initialize the layout. Now I want to do the same but using ListFragment.

I was using this exmaple as reference: http://developer.android.com/training/basics/fragments/creating.html

Below is modified code that I used for Fragment with a ListView. I have changed this to work with a ListFragment but without success. Can someone help me out? Thank you in advance.

    public class PlayersListFragment extends ListFragment {
    OnPlayerSelectedListener mCallback;

    // URL to make request
    private static String URL = Utils.URL;
    private static int userID;
    ArrayList<HashMap<String, Object>> playersList;
    ListView playerView;
    private Dialog pDialog;

    // The container Activity must implement this interface so the frag can
    // deliver messages
    public interface OnPlayerSelectedListener {
        /** Called by HeadlinesFragment when a list item is selected */
        public void onPlayerSelected(int position);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // We need to use a different list item layout for devices older than
        // Honeycomb
        int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? android.R.layout.simple_list_item_activated_1
                : android.R.layout.simple_list_item_1;

        // Create an array adapter for the list view, using the Ipsum headlines
        // array
        setRetainInstance(true);
        new PlayersLoadTask().execute();
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 
        initLayout();
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        return false;
    }


    private void initLayout() {         
        if(getActivity().getIntent()!=null) {
            userID = getActivity().getIntent().getIntExtra("id", 0);
        } else {
            return;
        }
        playerView = (ListView) getActivity().findViewById(R.id.list);
        playersList = new ArrayList<HashMap<String, Object>>();
        int[] colors = {0, 0xFFFF0000, 0}; // red for the example

    }
    @Override
    public void onStart() {
        super.onStart();

        // When in two-pane layout, set the listview to highlight the selected
        // list item
        // (We do this during onStart because at the point the listview is
        // available.)
        if (getFragmentManager().findFragmentById(R.id.playerDetailFragment) != null) {
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        }
    }


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception.
        try {
            mCallback = (OnPlayerSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnPlayerSelectedListener");
        }
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Notify the parent activity of selected item
        mCallback.onPlayerSelected(position);

        // Set the item as checked to be highlighted when in two-pane layout
        getListView().setItemChecked(position, true);
    }

    class PlayersLoadTask extends AsyncTask<String, String, String> {

        @Override
        protected void onPreExecute() {
            pDialog = ProgressDialog.show(getActivity(), "",
                    "Loading. Please wait...", true);
        }

        @Override
        protected String doInBackground(String... params) {
            try {

                ArrayList<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();
                parameters.add(new BasicNameValuePair("request", "getPlayers"));
                parameters.add(new BasicNameValuePair("clubid", Integer
                        .toString(userID)));

                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(URL);
                httpPost.setEntity(new UrlEncodedFormEntity(parameters,
                        ("ISO-8859-1")));
                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();

                // if this is null the web service returned an empty page
                if (httpEntity == null) // response is empty so exit out
                    return null;

                String jsonString = EntityUtils.toString(httpEntity);

                if (jsonString != null && jsonString.length() != 0) 
                {
                    JSONArray jsonArray = new JSONArray(jsonString);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        HashMap<String, Object> map = new HashMap<String, Object>();
                        JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                        int id = jsonObject.getInt("id");
                        String name = jsonObject.getString("name");

                        map.put("id", id);
                        map.put("name", name);
                        playersList.add(map);

                    }
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (Exception e) {
                Log.e("ERROR SOMEWHERE!!!! ", e.toString());
            }
            return null;

        }

        @Override
        protected void onPostExecute(String file_url) {
            if (pDialog.isShowing())
                pDialog.dismiss();
            if (playersList.size() == 0) {
                Toast.makeText(getActivity(), "No players in a list",
                        Toast.LENGTH_SHORT).show();
            } else {
                playerView.setAdapter(new PlayerListAdapter( // <<== EXCEPTION HERE
                        getActivity(), R.id.player_list_id,
                        playersList));
            }

        }
    }
}

And off course a stacktrace from a LogCat which points on this line : playerView.setAdapter(new PlayerListAdapter(

 12-18 11:34:30.181: E/AndroidRuntime(16436): FATAL EXCEPTION: main
12-18 11:34:30.181: E/AndroidRuntime(16436): java.lang.NullPointerException
12-18 11:34:30.181: E/AndroidRuntime(16436):    at com.statsports.statisticalandroid.PlayersListFragment$PlayersLoadTask.onPostExecute(PlayersListFragment.java:199)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at com.statsports.statisticalandroid.PlayersListFragment$PlayersLoadTask.onPostExecute(PlayersListFragment.java:1)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at android.os.AsyncTask.finish(AsyncTask.java:631)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at android.os.Handler.dispatchMessage(Handler.java:99)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at android.os.Looper.loop(Looper.java:137)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at android.app.ActivityThread.main(ActivityThread.java:5103)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at java.lang.reflect.Method.invokeNative(Native Method)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at java.lang.reflect.Method.invoke(Method.java:525)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-18 11:34:30.181: E/AndroidRuntime(16436):    at dalvik.system.NativeStart.main(Native Method)

Solution

  • That's how I solved my problem. Seem's you must include setListAdapter() in either onCreate() or onActivityCreated(). Code for future reference:

    public class PlayersListFragment extends ListFragment {
    OnPlayerSelectedListener mCallback;
    
    // URL to make request
    private static String URL = Utils.URL;
    private static int userID;
    ArrayList<HashMap<String, Object>> playersList;
    ListView playerView;
    private ProgressDialog pDialog;
    
    // The container Activity must implement this interface so the frag can
    // deliver messages
    public interface OnPlayerSelectedListener {
        /** Called by HeadlinesFragment when a list item is selected */
        public void onPlayerSelected(int position);
    }
    
    
    
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 
        setRetainInstance(true);
        initLayout();
    
        new PlayersLoadTask().execute();
        int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
                android.R.layout.simple_list_item_activated_1 : android.R.layout.simple_list_item_1;
        setListAdapter(new PlayerListAdapter(getActivity(), layout, playersList));
    
    }
    
    public boolean onOptionsItemSelected(MenuItem item) {
        return false;
    }
    
    
    private void initLayout() {         
        if(getActivity().getIntent()!=null) {
            userID = getActivity().getIntent().getIntExtra("id", 0);
        } else {
            return;
        }
        playerView = getListView();
        playersList = new ArrayList<HashMap<String, Object>>();
    
    }
    @Override
    public void onStart() {
        super.onStart();
    
        // When in two-pane layout, set the listview to highlight the selected
        // list item
        // (We do this during onStart because at the point the listview is
        // available.)
        if (getFragmentManager().findFragmentById(R.id.playerDetailFragment) != null) {
            playerView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        }
    }
    
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    
        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception.
        try {
            mCallback = (OnPlayerSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnPlayerSelectedListener");
        }
    }
    
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Notify the parent activity of selected item
        mCallback.onPlayerSelected(position);
    
        // Set the item as checked to be highlighted when in two-pane layout
        playerView.setItemChecked(position, true);
    }
    
    class PlayersLoadTask extends AsyncTask<String, String, String> {
    
        @Override
        protected void onPreExecute() {
            pDialog = ProgressDialog.show(getActivity(), "",
                    "Loading. Please wait...", true);
        }
    
        @Override
        protected String doInBackground(String... params) {
            try {
    
                ArrayList<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();
                parameters.add(new BasicNameValuePair("request", "getPlayers"));
                parameters.add(new BasicNameValuePair("clubid", Integer
                        .toString(userID)));
    
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(URL);
                httpPost.setEntity(new UrlEncodedFormEntity(parameters,
                        ("ISO-8859-1")));
                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
    
                // if this is null the web service returned an empty page
                if (httpEntity == null) // response is empty so exit out
                    return null;
    
                String jsonString = EntityUtils.toString(httpEntity);
    
                if (jsonString != null && jsonString.length() != 0) 
                {
                    JSONArray jsonArray = new JSONArray(jsonString);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        HashMap<String, Object> map = new HashMap<String, Object>();
                        JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                        int id = jsonObject.getInt("id");
                        String name = jsonObject.getString("name");
    
                        map.put("id", id);
                        map.put("name", name);
                        playersList.add(map);
    
                    }
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (Exception e) {
                Log.e("ERROR SOMEWHERE!!!! ", e.toString());
            }
            return null;
    
        }
    
        @Override
        protected void onPostExecute(String file_url) {
            if (pDialog.isShowing())
                pDialog.dismiss();
            if (playersList.size() == 0) {
                Toast.makeText(getActivity(), "No players in a list",
                        Toast.LENGTH_SHORT).show();
    
            } else if(playerView != null) {
                setListAdapter(new PlayerListAdapter(getActivity(),  R.id.player_list_id, playersList));
                /*playerView.setAdapter(new PlayerListAdapter(
                        getActivity(), R.id.player_list_id,
                        playersList));*/
            }
        }
    }