我已经读过这个:http://developer.android.com/guide/components/fragments.html
我正在将一些活动代码移动到一个全新的片段,但是之前在onCreate()中发现了代码问题。
使用片段的目的:制表符。
在每个标签页开关上调用代码:
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.tabContent, fragment1);
ft.commit();
其中fragment1,fragment2等是活动的实例变量,在onCreate
中实例化:
fragment1 = new Fragment1();
//etc.
onCreate()
将不会被调用,只会onResume()
。因为我只在onCreate()
初始化,所以没关系。我在onCreate()中调用一个web服务来获取数据以填充列表。根据片段的生命周期,有一些候选者可以放置这些代码,但没有一个完全起作用:
onCreate():在onCreateView()之前调用它。因此,视图层次结构尚未初始化,调用Web服务也不安全。
onCreateView():当我切换制表符/运行显示的代码片段时,总会调用此方法。
onActivityCreated():我认为在创建活动之后这将被称为 ,但在Fragment.onCreateView()
始终 >作为一个附带问题,您是否建议在片段中调用webservices?在网上没有找到任何相关信息,但不知道为什么不正确。
提前致谢!
答案 0 :(得分:1)
对我来说,onActivityCreated
或多或少似乎是匹配阶段(此时已经可以在父活动上调用findViewById
并在片段实例/集中设置组件/ assign字段(不要添加)听众。我的onActivityCreated
是这样的,不止一次运行它不会造成任何伤害,并且会考虑传递的Bundle
参数。
谈到Web服务,你可能可以从任何地方打电话,但你不能从GUI线程调用(Android不允许) - 所以创建自己的therad。您可能不需要支持在片段和活动之间完全切换,而某些对Web服务的调用正在等待处理;如果确实需要,请使用savedInstanceState
包来保存并在请求时恢复状态。
答案 1 :(得分:1)
使用装载程序:
创建AsyncLoader的子类,并在Fragment的onActivityCreated实现中启动/初始化这些加载器:
public abstract class MyLoader extends AsyncTaskLoader<String> {
public MyLoader(Context context) {
super(context);
}
private String result;
protected String error;
@Override
public final String loadInBackground() {
try {
error = null;
// Load your data from the server using HTTP and store result as string in 'result'.
...
result = ...
...
return result;
}
catch (Exception e) {
Logger.e("ResourceLoader", "Loading resource failed.", e);
error = e.getMessage();
}
return null;
}
@Override
protected void onStartLoading() {
if (!TextUtils.isEmpty(error)) {
deliverResult(result);
}
if (takeContentChanged()) {
forceLoad();
}
}
@Override
public void deliverResult(String data) {
if (isReset()) {
return;
}
result = data;
if (isStarted()) {
try {
super.deliverResult(data);
}
catch(Exception e) {
Log.e("ResourceLoader", "Caught exception while delivering result.", e);
}
}
}
public String getError() {
return error;
}
}
在Fragment中,您可以初始化此加载器:
public class Fragment1 extends Fragment implements LoaderCallbacks<String> {
....
....
String message;
TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
....
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = ....
...
textView = (TextView)view.findViewById(R.id.....);
textView.setMessage(message); // in case this Fragment1 survived an orientation change.
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(0, getArguments(), this); // Start loading data after activity has been created.
}
@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
return new MyLoader(getActivity()); // Load data using MyLoader
}
@Override
public void onLoadFinished(Loader<String> loader, String result) {
// Here you have the result in 'result'.
message = result;
if (textView != null) {
// Update UI according to result.
textView.setText(message);
....
}
...
}
....
}
在onLoadFinished中,将结果存储在“message”中。如果一个简单的String不足以作为结果,您可以更改MyLoader和LoaderCallbacks以返回并处理更复杂的数据结构(例如,List&lt; String&gt;)。