Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>I have a fragment that contains a button to bring up the contact list. Doing this requires calling [<code>startActivityForResult()</code>]</p> </blockquote> <p>The simplest answer is for you to call <code>startActivityForResult()</code> on the <code>Fragment</code> instead of the <code>Activity</code>. The result should be directed back to the fragment's own <code>onActivityResult()</code>.</p> <p>That being said, your approach appears to be a near-complete inversion over what I recommend. Fragments should not be starting activities. A fragment should neither know nor care how a particular UI event (e.g., button click) is handled for things that are outside the fragment itself. In this case, the activity should be responsible for obtaining the contact, with the fragment simply telling the activity "hey, this here button gots pressed, yo, and gimme a contact back". Not only is this important for separation of concerns, but it is important for testing, so you can test this behavior with mocked contact selections and such.</p> <blockquote> <p>Depending on how I include that fragment in my Activity layout, it may be several layers deep in other UI fragments</p> </blockquote> <p>You cannot nest fragments in fragments in Android. <a href="https://stackoverflow.com/questions/6847460/fragments-within-fragments/6847770#6847770">If you try, you will get unreliable results</a>.</p> <blockquote> <p>I don't want the top level UI to care about how the fragment is constructed at all.</p> </blockquote> <p>Activities absolutely must know how the fragment is constructed, since the activity is the one doing the constructing.</p> <p>Off the cuff, here is how I would approach it:</p> <ol> <li><p>Establish a listener interface for UI events raised by the fragment that transcend the bounds of the fragment itself. For the purposes of this answer, I'll call this <code>OnFooEventListener</code>.</p></li> <li><p>When the activity creates/configures the fragment, the activity supplies a <code>OnFooEventListener</code> instance to the fragment. That could be the activity itself, if the activity implements the interface.</p></li> <li><p>Establish a listener interface for the asynchronous pick-a-contact event that the fragment would like somebody to perform on its behalf. For the purposes of this answer, I'll call this <code>OnContactPickedListener</code>. It would have a method like <code>onContactPicked()</code> containing the <code>Uri</code> of the selected contact.</p></li> <li><p>On <code>OnFooEventListener</code>, have something like <code>requestContact()</code> that will be called when the user clicks the button. <code>requestContact()</code> would take an <code>OnContactPickedListener</code> instance as a parameter.</p></li> <li><p>The activity would do the <code>startActivityForResult()</code> call and, in <code>onActivityResult()</code>, call the associated <code>onContactPicked()</code> method on the <code>OnContactPickedListener</code>. The activity would cache those in a <code>HashMap</code> or something while the request was in process.</p></li> </ol> <p>Now, we have clear separation between the activity and the fragment. The fragment can still be hosted by any number of activities (e.g., one for a large screen, a different one for a normal screen). The contact can be supplied either by the production means (<code>ACTION_PICK</code>) or something else for testing (e.g., value established as part of the test case). The activity can deal with any number of such fragments without issue.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload