[英]When does a programmatically added fragment's view get created?
I have a FragmentActivity
that I add a single ListFragment
to using FragmentTrasaction
. 我有一个FragmentActivity
,我使用FragmentTrasaction
添加一个ListFragment
。 All fine and well, but I have run into the "Content view not created" errors when trying to set the onItemClickListener
of the ListView
in the ListFragment
, like this: 一切都很好,但是当我尝试在onItemClickListener
中设置ListView
的ListFragment
,我遇到了“内容视图未创建”错误,如下所示:
public class ContactList extends FragmentActivity implements
LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener {
static private final String TAG = ContactList.class.getSimpleName();
private SimpleCursorAdapter mListAdapter;
ListFragment mListFrag;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mListFrag = new ListFragment();
if (savedInstanceState == null) {
// add list view fragment
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.add(android.R.id.content, mListFrag);
ft.commit();
}
// set up list view adapter:
mListAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, null,
new String[] { ContactsContract.Contacts.DISPLAY_NAME },
new int[] { android.R.id.text1 },
SimpleCursorAdapter.NO_SELECTION);
// (we will switch in the cursor later)
mListFrag.setListAdapter(mListAdapter);
// set list view click listener:
// (THIS LINE, I KNOW NOW, CAUSES PROBLEMS - SO I MOVED IT
// TO onCreateView):
//mListFrag.getListView().setOnItemClickListener(this);
// initial cursor loader:
getSupportLoaderManager().initLoader(0, null, this);
}
I quickly realised that I was trying to call getListView
in the onCreate
method, so the ListView
was not being shown yet. 我很快意识到我试图在onCreate
方法中调用getListView
,因此ListView
尚未显示。 So, I moved the line setOnItemClickListener
line to onCreateView
: 所以,我将setOnItemClickListener
行移动到onCreateView
:
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
View v = super.onCreateView(name, context, attrs);
// set list view click listener:
mListFrag.getListView().setOnItemClickListener(this); // this still crashes
return v;
}
Unfortunately, this still crashes with a "Content view not yet created" error. 不幸的是,这仍然会因“尚未创建内容视图”错误而崩溃。 I don't understand this - surely after calling super.onCreateView
all of the views should have now been created? 我不明白这一点 - 在调用super.onCreateView
之后肯定应该创建所有的视图吗?
I finally got the inItemClickListener
to work by putting it on 'onResume()', but I don't know why it did't work in onCreateView
. 我终于通过将它放在'onResume()' inItemClickListener
使inItemClickListener
工作,但我不知道为什么它在onCreateView
不起作用。
Can anyone enlighten me? 任何人都可以开导我吗?
Thanks. 谢谢。
Fragment
s have own lifecycles and as I recall you can not set listeners on default Fragment
lifecycle events from within the containing FragmentActivity
(or any other Activity
). Fragment
有自己的生命周期,我记得你不能在包含FragmentActivity
(或任何其他Activity
)的默认Fragment
生命周期事件中设置监听器。 Therefore, you can not be sure if the list view has been created already if you use the default ListFragment
. 因此,如果使用默认的ListFragment
,则无法确定是否已创建列表视图。
I finally got the inItemClickListener to work by putting it on 'onResume()', but I don't know why it did't work in onCreateView. 我终于通过将它放在'onResume()'上来使inItemClickListener工作,但我不知道为什么它在onCreateView中不起作用。
This might work for you, but also isn't safe because it has no knowledge of the Fragment's lifecycle state. 这可能对您有用,但也不安全,因为它不了解Fragment的生命周期状态。
The default/best practice here is the following: write your own Fragment class, let it extend ListFragment
and put the onClick logic in the onListItemClick()
method of your fragment. 这里的默认/最佳实践如下:编写自己的Fragment类,让它扩展ListFragment
并将onClick逻辑放在片段的onListItemClick()
方法中。
Background: 背景:
Setting any listeners on UI events of a Fragment should happen inside the Fragment itself, not in the containing Activity. 在Fragment的UI事件上设置任何侦听器应该在Fragment本身内部发生,而不是在包含Activity中。 That's one of the reasons why Fragments have been introduced: to provide mostly independent components (with an own lifecycle) that can be combined and re-used. 这就是为什么引入Fragments的原因之一:提供可以组合和重用的大多数独立组件(具有自己的生命周期)。 Otherwise, you could just use a ListActivity
. 否则,您可以使用ListActivity
。
OnCreateView创建一个视图,使其在返回后可用,但不能在执行之前或执行期间使用。
After ft.commit
just call getSupportFragmentManager().executePendingTransactions();
ft.commit
之后只需调用getSupportFragmentManager().executePendingTransactions();
( executePendingTransactions ). ( executePendingTransactions )。
This forces the system to immediately execute the ft.commit
which is only scheduled to be executed by default. 这会强制系统立即执行仅默认执行的ft.commit
。
After that your ListView should be ready to be accessed to define the OnClickListener
(inside your FragmentActivity
) 之后,您的ListView应该可以访问以定义OnClickListener
(在FragmentActivity
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.