【问题标题】:External AsyncTask populating ListView from Fragment从 Fragment 填充 ListView 的外部 AsyncTask
【发布时间】:2012-11-20 13:14:39
【问题描述】:

我正在开发基于片段的应用程序。这些片段的许多内容是从使用AsyncTask 的数据库中收集的。因此,我正在尝试将“获取数据”类外部化,以便可以重用它。我的片段如下:

public class LocalFragment extends SherlockListFragment {

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);

        LoadDataFromURL url_data = new LoadDataFromURL();
        url_data.setContext(getSherlockActivity());
        url_data.setURL("http://url.com/get_data/");
        url_data.execute();

    }

} 

我的LoadDataFromURL类如下:

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

    String our_url;
    ListActivity our_context;
    private ProgressDialog pDialog;
    JSONParser jParser = new JSONParser();
    JSONArray results = null;
    List<PubListDetails> pubs = new ArrayList<PubListDetails>();
    Handler mHandler;

    public void setContext(ListActivity context){
        our_context = context;
    }

    public void setURL(String url){
        our_url = url;
    }

    ArrayList<HashMap<String, String>> productsList = new ArrayList<HashMap<String, String>>();

    @Override
    protected void onPreExecute() {

        // TODO Auto-generated method stub
        super.onPreExecute();

        mHandler = new Handler();

        pDialog = new ProgressDialog(our_context);
        pDialog.setMessage("Loading pubs please wait..");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    @Override
    protected String doInBackground(String... args) {
        // TODO Auto-generated method stub

        List<NameValuePair> params = new ArrayList<NameValuePair>();

        JSONArray json = jParser.makeHttpRequest(our_url, "GET", params);


        Log.d("All Products: ", json.toString());


        try {
            int success = json.length();

            if (success != 0){
                results = json;

                pubs.clear();


                for (int i = 0; i <results.length(); i++){
                    JSONObject c = results.getJSONObject(i);

                    String id = c.getString("id");
                    String name = c.getString("name");
                    String town = c.getString("town");
                    String county = c.getString("county");

                    //HashMap<String, String> map = new HashMap<String, String>();


                    pubs.add(new PubListDetails(id,name,town,county));
                    //map.put(TAG_PID, id);
                    //map.put(TAG_NAME, name);

                    //productsList.add(map);
                }
                }else{
                    Intent i = new Intent(our_context,MainMenu.class);

                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    our_context.startActivity(i);
                }
            } catch (JSONException e){
                e.printStackTrace();
                }

        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        Toast.makeText(our_context, "ff", Toast.LENGTH_SHORT).show();
        // TODO Auto-generated method stub
        pDialog.dismiss();

our_context.runOnUiThread(new Runnable(){

    @Override
    public void run() {
        // TODO Auto-generated method stub
        ListAdapter adapter = new PubListAdapter(our_context, pubs);
        our_context.setListAdapter(adapter);
    }});

    }   

}

这是因为getSherlockActivity 没有通过ListActivity,这是setListAdapter 要求的。

除此之外,我越来越觉得我在概念上错过了重点,这不是实现我想要的理想方式。

有人可以建议我如何从片段中调用外部AsyncTask,它将收集数据然后用它填充ListView

【问题讨论】:

    标签: android android-asynctask android-fragments


    【解决方案1】:

    首先,您想在SherlockListFragment 上设置数据,因此您的业务不在Activity 上。

    独立于此,我越来越觉得自己拥有 在概念上错过了重点,这不是实现的理想方式 我想要什么。

    有人可以建议我如何从片段中调用外部 AsyncTask 将收集数据然后填充列表视图 它..?

    只需实现一个回调接口。

    public interface OnLoadDataListener {
          public onLoadComplete(List<PubListDetails> data);
    }
    

    让你的片段类实现这个接口:

    public class LocalFragment extends SherlockListFragment implements OnLoadDataListener {
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {    
            super.onActivityCreated(savedInstanceState);
            LoadDataFromURL url_data = new LoadDataFromURL();
            url_data.setContext(getSherlockActivity());
            url_data.setURL("http://url.com/get_data/");
            url_data.setListener(this); // you could unite the setContext() method in the listener registration
            url_data.execute();
        }
    
        @Override
        public void onLoadComplete(List<PubListDetails> data) {
             ListAdapter adapter = new PubListAdapter(getSherlockActivity(), pubs);
             our_context.setListAdapter(adapter);
        }
    }
    

    在你的AsyncTask:

    private OnLoadDataListener mListener
    
    public void setListener(OnLoadDataListener listener){
        mListener = listener;
    }
    

    并在onPostExecute 中将数据发送给监听器:

    @Override
    protected void onPostExecute(String result) {
        Toast.makeText(our_context, "ff", Toast.LENGTH_SHORT).show();
        // TODO Auto-generated method stub
        pDialog.dismiss();
        if (mListener != null) {
            mListener.onLoadComplete(pubs);
        }
    }
    

    【讨论】:

    • 所以.. 据我了解,这一切本质上都是回调我的片段中包含的 onLoadComplete 方法。然后我可以使用数据设置列表适配器,但是如何将其加载到视图中......?另外..是的,它可以工作..但是这里实际上在听什么?例如,没有点击。谢谢
    • @ThomasClowes 该接口抽象了AsyncTask 和将使用任务检索到的数据的组件之间的连接。代码基本上说:(从片段的角度来看)我正在创建此任务以获取数据,并且我将自己注册为侦听器(通过实现onLoadComplete 方法),以便我可以使用检索到的数据。 AsyncTask 将像往常一样获取数据,当它完成时,它会看到有对该数据感兴趣的组件(mListener 不是 null),因此它将数据转发给该注册的侦听器。
    • @ThomasClowes 使用此代码,AsyncTask 不知道谁使用该数据(它并不关心)。侦听器可以是您的列表片段、活动、普通片段等,任何实现接口的onLoadComplete 方法(并注册为任务的侦听器)的人,因为这是任务唯一知道的事情。我不明白您在谈论 将其加载到视图中时指的是什么。
    • 太棒了。非常感谢 !我的查询的最后一个方面如下:所以我已经从 AsyncTask 获取数据到我注册的监听器,但是我怎么知道加载我的列表视图。如果我的数据是一个静态数组,我只需在片段的 onCreateView 方法中对其进行膨胀。谢谢
    • 正如我所料,我很愚蠢。这是我的 LoadDataFromURL 中的一个错误,这意味着视图没有加载。谢谢你的帮助。我认为 setListAdapter 在当前设置的任何视图中运行(本身)是否正确?
    猜你喜欢
    • 2018-03-25
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多