"自动" ProgressDialog不会被解雇

时间:2014-07-31 16:11:14

标签: android progressdialog

当我启动我的应用程序时,第一个活动使用AsyncTask从外部源加载数据。一个ProgressDialog,带有文字" Loading ..."得到了显示,但是当新闻项片段加载时,对话框仍然可以看到片段顶部。

我在AsyncTask中调用另一个ProgressDialog(也会显示),但它似乎是一个不同的,因为当我将上述AsyncTask注释掉时,其他ProgressBar仍覆盖渲染的片段。

这里的大多数问题都与实际调用的ProgressBars有关,我不会在任何地方实例化另一个问题。

由于

更新:接受回答

activity_news.xml:必须删除ListView元素,因为引用Fragment是一个ListFragment

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <ListView android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

NewsListFragment.java:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    context = getActivity();
    adpt = new NewsArrayAdapter(new ArrayList<NewsItem>(), context);
    ListView listView = getListView();
    listView.setAdapter(adpt);
    listView.setOnItemClickListener(new NewsItemOnClickListener());
    startNewAsyncTask();
}

@Override
public void taskFinished(List<NewsItem> result) {
    setListShown(true);
    dialog.dismiss();
    adpt.setItemList(result);
    adpt.notifyDataSetChanged();
}

解决了它!

2 个答案:

答案 0 :(得分:0)

首先,你在AsyncTask中保持对Activity的强引用时犯了很大的错误。其次,这一行new WeakReference<NewsAsyncTask>(asyncTask);对你没有任何作用。

所以我要这样做:

  • AsyncTask
  • 中介绍回调界面
  • 通过WeakReference
  • 创建对回调的引用
  • 删除对Adapter,Context和Dialog的依赖

<强>的AsyncTask

public class NewsAsyncTask extends AsyncTask<String, Void, List<NewsItem>> {
    private final WeakReference<NewsTaskCallback> weakCallback;

    public interface NewsTaskCallback {
        void taskStarted();
        void taskFinished(List<NewsItem> result);
        void taskCancelled();
    }

    public NewsAsyncTask(NewsTaskCallback callback) {
        weakCallback = new WeakReference<NewsTaskCallback>(callback);
    }

    @Override
    protected void onCancelled() {
        super.onPreExecute();
        NewsTaskCallback c = weakCallback.get();
        if (c != null) {
            c.taskCancelled();
        }
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        NewsTaskCallback c = weakCallback.get();
        if (c != null) {
            c.taskStarted();
        }
    }

    @Override
    protected void onPostExecute(List<NewsItem> result) {
        super.onPostExecute(result);
        NewsTaskCallback c = weakCallback.get();
        if (c != null) {
            c.taskFinished(result);
        }
    }

    ....
}

现在,在您的片段中执行以下操作:

  • 实施NewsTaskCallback
  • 处理在回调方法中显示和隐藏Dialog
  • 处理taskFinished()
  • 中的适配器更新
  • 将启动任务移至onActivityCreated()
  • 的末尾

<强>片段

public class NewsListFragment extends ListFragment implements NewsTaskCallback {
    private ProgressDialog dialog;
    private NewsArrayAdapter adpt;
    private NewsAsyncTask asyncTask;
    private static final String URL = "http://lisateam.lisa-is.nl/XmlServices_v2/News/GetClubNews.aspx";

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        adpt = new NewsArrayAdapter(new ArrayList<NewsItem>(), context);
        ListView listView = (ListView) getActivity().findViewById(R.id.listview);
        listView.setAdapter(adpt);
        listView.setOnItemClickListener(new NewsItemOnClickListener());
        startNewAsyncTask();
    }

    @Override
    public void taskStarted() {
        dialog = ProgressDialog.show(context, "Een moment geduld...", "De nieuwsberichten worden geladen");
    }

    @Override
    public void taskFinished(List<NewsItem> result) {
        dialog.dismiss();
        adpt.setItemList(result);
        adpt.notifyDataSetChanged();
    }

    @Override
    public void taskCancelled() {
        if (dialog != null) {
            dialog.dismiss();
        }
    }

    ....

    private void startNewAsyncTask() {
        if (asyncTask != null) {
            asyncTask.cancel(false);
            asyncTask = null;
        }
        if (dialog != null) {
            dialog.dismiss();
        }
        asyncTask = new NewsAsyncTask(this);
        asyncTask.execute(URL);
    }
}

使用上述代码,您将获得一些好处:

  • 您可以根据需要多次调用startNewAsyncTask(),当前正在运行的任务将在新任务启动之前正确完成
  • 一次只能有一个对话框,您不应再看到重复项
  • 在AsyncTask运行时,可以销毁Activity(带有你的片段),现在可以通过正确使用WeakReference来处理它。

答案 1 :(得分:0)

我认为在onPostExecute()中的任务内部可以调用“dialog.dismiss()”。但首先检查对话框是否!= null。

修改
作为建议,如果您使用asyncTask,则可以定义Handler并将其传递给任务。任务完成后,您可以将结果传递给处理程序,该处理程序使用result设置列表的适配器。主要与关注点分离有关。

编辑2:
我发现你可以在加载数据时使用它:

setListShown(true);

希望它能解决问题:D

编辑3:
我有另一个建议。在ListFragment中,您将从“活动”布局中获取列表视图。在概念上有点不对劲。从活动布局中删除listview,在ListFragment中只需使用getListview()。这种片段提供了一个列表视图,这就是它被调用的原因。