带有Asynctask和自定义适配器的ListFragment

时间:2013-12-18 11:41:32

标签: android android-fragments android-asynctask android-listfragment

我的问题非常基本,但是我看不到它的解决方案。这是我在Android上的第三个项目。 到目前为止,我正在使用其中声明了ListView的片段,onCreateView我在其中充气我的ListView和onActivityCreated来初始化布局。现在我想使用ListFragment做同样的事情。

我使用这个例子作为参考:http://developer.android.com/training/basics/fragments/creating.html

下面是我用于ListView的修改代码。我已将此更改为使用ListFragment,但没有成功。有人可以帮我吗?先感谢您。

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

        }
    }
}

当然还有来自LogCat的堆栈跟踪指向此行: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)

2 个答案:

答案 0 :(得分:2)

onActivtiyCreated中,您拨打initLayout(),其中包含以下内容

playerView = (ListView) getActivity().findViewById(R.id.list);

以上是导致NullPointerException

的原因

所以改为

 playerView = getListView();   // since you extend ListFragment

答案 1 :(得分:1)

这就是我解决问题的方法。看来你必须在onCreate()或onActivityCreated()中包含setListAdapter()。代码供将来参考:

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));*/
        }
    }
}