从AsyncTaskLoader onLoadFinished后动态更新片段的UI - 无法获取ViewGroup
以前,我有一个Fragment
,它根据耗时的提取数据更新其UI。从AsyncTaskLoader onLoadFinished后动态更新片段的UI - 无法获取ViewGroup
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
间接更新它的UI。
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);
}
....
}
因为我没有使用ListFragment
我没有一个ArrayAdapter
。我想要做的是将几个TextView
添加到几个LinearLayout
。然后,我会将LinearLayout
添加到Fragment
的容器中。
但是,下面的代码给我空指针异常。
ViewGroup container = (ViewGroup)this.getView().getParent();
我所知道的是动态更新分段UI,onLoadFinished
从AsyncTaskLoader
后正确的方法是什么?
但是,我遇到的大多数例子是,他们通过ArrayAdapter间接更新他们的UI 。
使用Loader
不要求你必须使用一个ListView
,你可以更新你的应用程序的目标是无论大家认为。
我知道什么是从AsyncTaskLoader onLoadFinished后动态更新Fragment UI的正确方法, ?
从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);;
}
有一段时间我也试图达到同样的效果。基于以上的答案,什么工作对我来说是这样的:
@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已更改。
您可以随意使用背景设置,使用可绘制图像而不是颜色,这取决于您。
谢谢。在从'onCreateView'返回之前,我可以确认从R.layout.home_menu膨胀的View是一个ScrollView(正确,因为home_menu XML的根是ScrollView)。然而,当我在onLoadFinished中调用getView时,我得到了'android.support.v4.app.NoSaveStateFrameLayout'。我可以知道什么是我得到ScrollView的正确方法吗? – 2013-03-20 07:38:43
@CheokYanCheng你不要简单地使用'getView()'。你为要放置视图的ViewGroup分配一个id(我使用了'R.id.containerId'),并且寻找该视图(在getView()')上使用'findViewById()'来添加额外的意见。 – Luksprog 2013-03-20 07:42:12
好的。感谢这项技术。我以为我需要在'onLoadFinished'内提供容器及其所有UI元素。实际上,我可以在'onCreateView'中提供容器,然后通过'onLoadFinished'添加新的UI元素 – 2013-03-20 12:16:32