【问题标题】:View overlap after updating fragment with Asynctask使用 Asynctask 更新片段后查看重叠
【发布时间】:2013-12-08 22:44:08
【问题描述】:

我假装是显示一个不确定的进度条(目前只是一个用于测试目的的对话框),而我的第二个片段正在获取数据并在不冻结 UI 的情况下构建视图。

我尝试过的:

  • 异步任务
  • 加载器
  • 带 AsyncTaskLoader 的加载器
  • 适配器(未尝试但可能是一个选项,但我不知道如何 使用带有自定义布局的适配器)

使用 asynctask 方法几乎一切都是正确的,但是 onPostExecute 我必须更新片段才能做到这一点,我创建了一个界面,在主活动中我删除了视图并添加了新的视图,但是这样我又产生了另一个问题我的后台堆栈搞砸了,所以我没有选择。

帮助理解其工作原理的图表:

我的片段 2:

public class FragTopics extends Fragment {

Object course;
ManSession session;
String courseId;
Long topicId;
String courseName;
private LinearLayout mainLayout;
private ScrollView contentScrollable;
private LinearLayout contentsLayout;
private View myView;

public FragTopics() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    session = new ManSession(getActivity().getApplicationContext());

    courseId = getArguments().getString("courseId");
    topicId = Long.parseLong(getArguments().getString("topicId"));
    courseName = getArguments().getString("courseName");

    new HeavyWork().execute();

    // Create empty view because i need to return something
    myView = new View(getActivity());
    return myView;
}

private class HeavyWork extends AsyncTask<Void, Void, Void> {
    private ProgressDialog dialog;
    final FragmentUpdater activity = (FragmentUpdater) getActivity();

    // Do the long-running work in here
    @Override
    protected Void doInBackground(Void... params) {

        MoodleCourseContent[] courseTopics = new ManContents(getActivity()
                .getApplicationContext()).getContent(courseId);

        MoodleCourseContent singleTopic = new ManContents(getActivity()
                .getApplicationContext()).getTopic(topicId, courseTopics);

        // This createTopics call another methods from the fragment class to
        // get the data and create views
        myView = createTopics(singleTopic, courseName, courseId, topicId);
        return null;

    }

    protected void onPreExecute() {
        dialog = new ProgressDialog(getActivity());
        dialog.show();
    }

    // This is called when doInBackground() is finished
    @Override
    protected void onPostExecute(Void ignore) {
        activity.updater(myView);
        dialog.dismiss();
    }

}

我的界面:

    public interface FragmentUpdater {

    public void updater(View param);

}

我实现接口的主要活动:

@Override
    public void updater(View param) {
         ViewGroup vg = (ViewGroup) findViewById (R.id.main_content);
         vg.removeAllViews();
         vg.addView(param);
    }

我的布局是程序化创建的,这是结构:

->LinearLayout
  ->TextView
  ->ScrollView
    ->LinearLayout 

我的主要问题是如何在片段 2 初始化时显示进度条而不冻结 UI,如果我的上述方法是正确的,那么在完成繁重工作后如何更新片段中的视图,换句话说asyncTask 完成后台工作

删除所有视图并添加新视图后,onBackpressed 将与之前的片段视图重叠我的视图

【问题讨论】:

  • 你的主要问题是什么?我不明白你在问什么?
  • 我更新了问题,我的主要问题是如何在片段 2 初始化时显示进度条而不冻结 UI,如果我的上述方法是正确的,如何在片段之后更新视图换句话说,在 asyncTask 完成后台工作之后完成了重工作。但是在给出负分之前阅读所有内容

标签: android android-fragments android-asynctask


【解决方案1】:

您的片段是无头的。所以不要实现 onCreateView 方法。将该代码移至 onCreate。然后在异步任务中,使用 onPostExecute 向父活动发送更新信息以使其显示。然后,该片段的父 Activity 可以决定 UI 应如何响应此信息。确保您避免在除 onPostExecute(或 onPublishProgress,如果您正在更新)方法之外的任何地方与父活动通信,因为 a) 活动可能由于多种原因为空,包括设备旋转和 b) 这些方法是保证在 UI 线程上运行

【讨论】:

  • ok 是有道理的,但我如何设置该片段的内容视图?换句话说,我如何将在 Asynctask 中创建的视图设置为片段?我需要返回一个视图,这就是主要问题的根源
  • 任务代码只有在工作完成后才会到达onPostExecute。所以 UI 并没有陷入困境,它只是没有被更新。与主 UI 线程的通信必须通过 RunnableActivity 排队,如果您在 doInBackground 正在运行的单独线程上:activity.runOnUiThread(new Runnable(...)); 您可能想看看这个以了解如何将长时间运行的任务与 Android 中的 UI 集成:Retaining Objects Across Config Changes
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多