简体   繁体   中英

When does a programmatically added fragment's view get created?

I have a FragmentActivity that I add a single ListFragment to using FragmentTrasaction . 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:

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. So, I moved the line setOnItemClickListener line to 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?

I finally got the inItemClickListener to work by putting it on 'onResume()', but I don't know why it did't work in 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 ). Therefore, you can not be sure if the list view has been created already if you use the default 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.

This might work for you, but also isn't safe because it has no knowledge of the Fragment's lifecycle state.

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.

Background:
Setting any listeners on UI events of a Fragment should happen inside the Fragment itself, not in the containing 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. Otherwise, you could just use a ListActivity .

OnCreateView创建一个视图,使其在返回后可用,但不能在执行之前或执行期间使用。

After ft.commit just call getSupportFragmentManager().executePendingTransactions(); ( executePendingTransactions ).

This forces the system to immediately execute the ft.commit which is only scheduled to be executed by default.

After that your ListView should be ready to be accessed to define the OnClickListener (inside your FragmentActivity )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM