3

以前,我有一个Fragment,它根据耗时的获取数据更新其 UI。

public class HomeMenuFragment extends SherlockFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        Infos arg1 = performTimeConsumingDataStructureLoading();

        // Add in various UI views in v, according to information in loaded
        // data structure.
        View v = inflater.inflate(R.layout.home_menu, container, false);
        // ...
        // Adding several LinearLayout and TextView into v, based on
        // information from loaded data structure (arg1)
        // ...
        return v;
    }
    ....
}

这真的不是一个好的设计。有时,performTimeConsumingDataStructureLoading可能需要超过 5 秒,我会得到 ANR(应用程序无响应)

通过参考http://developer.android.com/reference/android/content/AsyncTaskLoader.html,我最终得到了更好的解决方案。我遇到的例子是,它通过ArrayAdapter.

public class HomeMenuFragment extends SherlockFragment implements LoaderManager.LoaderCallbacks<HomeMenuFragment.Infos> {
    @Override
    public void onLoadFinished(Loader<Infos> arg0, Infos arg1) {
        LayoutInflater inflater = this.getLayoutInflater(null);
        ViewGroup container = (ViewGroup)this.getView().getParent();
        // Remove previous old views, as onLoadFinished might be triggered
        // by onContentChanged too.
        container.removeAllViews();

        View v = inflater.inflate(R.layout.home_menu, container, false);
        // ...
        // Adding several LinearLayout and TextView into v, based on
        // information from loaded data structure (arg1)
        // ...
        container.addView(v);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }     
    ....
}

我没有,ArrayAdapter因为我没有使用ListFragment. 我想要做的是将几个TextView加到几个LinearLayout中。然后,我将添加LinearLayoutFragment's 容器中。

但是,以下代码给了我空指针异常。

ViewGroup container = (ViewGroup)this.getView().getParent();

我知道在onLoadFinishedfrom之后动态更新 Fragment UI 的正确方法是什么AsyncTaskLoader

4

2 回答 2

4

但是,我遇到的大多数示例是,它们通过 ArrayAdapter 间接更新其 UI。

使用 aLoader并不要求您必须使用 a ListView,您可以更新您在应用程序中定位的任何视图。

我知道在从 AsyncTaskLoader 的 onLoadFinished 之后动态更新 Fragment UI 的正确方法是什么?

从 's 视图获取对容器的引用Fragment,您将在其中放置额外视图并添加新视图。

@Override
public void onLoadFinished(Loader<Infos> arg0, Infos arg1) {      
    // for some reason the fragment's view isn't built yet so abort things 
    if (getView() == null) {
         ViewGroup container = (ViewGroup) getView().findViewById(R.id.containerId);
         ViewGroup container = getViewcontainer.removeAllViews();
         // ...
         // Adding several LinearLayout and TextView into v, based on
         // information from loaded data structure (arg1)
         // ...
         container.addView(v);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    return inflater.inflate(R.layout.home_menu, container, false);;
}    
于 2013-03-20T07:12:50.710 回答
0

有一段时间我也试图达到同样的效果。基于上述答案,对我有用的是:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    adapter.swapCursor(cursor);

    ViewGroup container = (ViewGroup) getView().findViewById(R.id.fragment_oam);

    if (container != null) {
        if (adapter.getCount() == 0) {
            Log.v(TAG, "Count is: " + adapter.getCount());
            container.setBackgroundColor(Color.BLUE);
        } else {
            Log.v(TAG, "Count is: " + adapter.getCount());
            container.setBackgroundColor(Color.WHITE);
        }   
    } else {
        Log.v(TAG, "Container is null");
    }
}

我的布局xml如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/background"
    android:background="#FFF">    
<fragment
    android:name="com.myapp.OAMCursorLoader"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment_oam">
</fragment>

现在,当 ContentResolver 更新光标时,onLoadFinished 会根据可见屏幕的这个背景检查光标是否为空或是否有一些内容,即 ListFragment 已更改。

您可以使用背景设置,使用可绘制图像而不是颜色,这取决于您。

于 2014-10-11T14:39:56.620 回答