1

I just implemented the friend picker using Facebook's provided SDK fro Android. Everything seems to be working fine except for if a user wants to go back into the picker and edit their friend selection. I'm able to get the previously selected friends, and call setSelection on the friendPickerFragment (which receives the List object, confirmed via Log.d). However, the friends are NOT being pre-selected!! In my PickerActivity I am calling:

@Override
protected void onResume() {
    super.onResume();
    if (FRIEND_PICKER.equals(getIntent().getData())) {
        Log.d(LOG, "HERE");
        try {
            if (selectedFriends()!=null) {
                Log.d(LOG, "U HAVE FRIENDS: " + selectedFriends().size());
                friendPickerFragment.setSelection(selectedFriends());
            }
            friendPickerFragment.setFriendPickerType(FriendPickerType.TAGGABLE_FRIENDS);
            friendPickerFragment.loadData(false);
        } catch (Exception ex) {
            onError(ex);
        }
    }
}

I've also tried only calling setSelection, thinking that perhaps the call to loadData was wiping out the selections... but still no luck. I've also noticed tht for my PickerActivity (as designed by the Scrumptious fb tutorial) onCreate is called everytime I open the friend picker... likely forcing a reload of the data. Does anyone have experience getting this to work? I'm stumped at the moment. Thanks in advance.

Warblr
  • 1,188
  • 1
  • 13
  • 27
  • I found this [thread](http://stackoverflow.com/a/23371788/1542275) which demonstrates exactly what I'm doing, however I cannot get any preselected friends. I can however see that the `public void setSelectionByIds(List userIds)` method is processing the userIds I send to it. Just not sure why the UI is not cooperating. – Warblr Sep 09 '14 at 16:46
  • OK, so I've tracked this the whole way to the facebook sdk class `PickerFragment` where I can see that the correct userIds are being toggled on correctly: `@Override void toggleSelection(String id)` But why is the UI (i.e., ListItem checkboxes) not updating????!!!!! What happens after `selectedIds.add(id);` to tell the UI to update? – Warblr Sep 09 '14 at 21:03
  • I added Facebooks FriendPickerSample to my workspace, ran it, and it works as expected with previously selected users remaining selected... I tried it's implementation but no luck. What I notice is that my savedInstanceState is null everytime I launch the picker, so I'm guessing this is related to the issue as I'm creating a new picker everytime... – Warblr Sep 09 '14 at 21:57
  • OK, so it appears that my fragment for the friendpicker is being instantiated everytime instead of being pulled from the fragmentmanager... not sure why that is, but is likely the problem. – Warblr Sep 09 '14 at 22:41
  • So what I've found is that FragmentManager is not retaining fragments?! when I cann getFragmentManager().getFragments() it returns null... I'm going to implement things exactly as the facebook FriendPickerSample and move forward from there... – Warblr Sep 10 '14 at 01:37
  • After sleeping - I found that Facebooks sample app FriendPickerSample also does not retain previously selected friends if you change the FriendPickerType to `FriendPickerType.TAGGABLE_FRIENDS` - it only works with the default type `FriendPickerType.FRIENDS`, which unfortunately only allows the tagging of other people who are also using your app. WTH? – Warblr Sep 10 '14 at 16:50
  • Exploring Facebooks FriendPickerFragment I found that the `TAGGABLE_FRIENDS` type is set to not cacheable... if I change it to `cacheable = true` the previously selected friends are 'checked' momentarily when the view loads again, then they 'uncheck'... exploring why now. – Warblr Sep 10 '14 at 16:58

1 Answers1

2

To understand this response you'll need to read my comments under the original question above.

What I found: When you change Facebook's FriendPickerFragment to type FriendPickerType.TAGGABLE_FRIENDS the data returned is setup not to be cached. This means that every time the friend picker is shown the data is reloaded, which for some reason causes any previously selected friends not to be reselected after the reload completes. I'm still not sure why that is, because it seems like the FriendPickerFragment still has reference to those selected friends via it's preSelectedFriendIds List<String> object (So a better solution may be determining why that is happening). Furthermore, if you change the FriendPickerType.TAGGABLE_FRIENDS to allow caching, when you relaunch the FriendPickerFragment you momentarily see that your previously selected friends are in-fact selected, but then the FriendPickerFragment realizes that it loaded data (even if only some) from the cache, which causes it to refresh it's data! Again, resetting the previously selected friends!

What I did to workaround: This is perhaps not the best way to go about this, as I'm sure Facebook made the FriendPickerType.TAGGABLE_FRIENDS non-cacheable for a reason. My initial thinking is that it's because if it's loading from the cache it may not always contain the users full list of friends, or perhaps it's just a lot of friends (data) to cache. However, I switched the type to cacheable. Then I added a boolean to the FriendPickerFragment that indicates whether or not this is the first time the data has been loaded. If you follow the Facebook tutorial you'll see that they setup the FriendPickerFragment using a static method named populateParameters(Intent intent, String userId, boolean multiSelect, boolean showTitleBar, boolean initialLoad). Before launching the FriendPicker I check in my launching Activity if the FriendPicker has already been shown or not. If it hasn't I set the initialLoad boolean to true, otherwise if it has already been shown I set the initial boolean to false. This boolean controls the onLoadFinished() method found in Facebook's FriendPickerFragment under the private class ImmediateLoadingStrategy:

    private class ImmediateLoadingStrategy extends LoadingStrategy {
    @Override
    protected void onLoadFinished(GraphObjectPagingLoader<GraphUser> loader, SimpleGraphObjectCursor<GraphUser> data) {
        super.onLoadFinished(loader, data);
        // We could be called in this state if we are clearing data or if we are being re-attached
        // in the middle of a query.
        if (data == null || loader.isLoading()) {
            return;
        }
        if (data.areMoreObjectsAvailable()) {
            // We got results, but more are available.
            followNextLink();
        } else {
            // We finished loading results.
            hideActivityCircle();

            // If this was from the cache, schedule a delayed refresh query (unless we got no results
            // at all, in which case refresh immediately.
            if (data.isFromCache() && initialLoad==true) {
                loader.refreshOriginalRequest(data.getCount() == 0 ? CACHED_RESULT_REFRESH_DELAY : 0);
            }
        }
    }
}

Note the added check && initialLoad==true - this (a) makes sure that if this is the first time the friendpicker is shown the friends list is updated and (b) if it has already been shown once during this run of the app, it is not refreshed. This ensures that the previously selected friends remain selected.

If someone has a better solution I'd love to hear it :)

Warblr
  • 1,188
  • 1
  • 13
  • 27