Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Ankit B
4,180 PointsEditFriendsFragment not working as expected in the Ribbit app
Hi Ben,
I am using EditFriendsFragment instead of just Activity and everything was working fine with your code. But then I tried to optimize the addFriendsCheckmark() method which was O(n^2) and replaced it with an O(n) method using a HashMap. The problem: when I add a checkmark to my friends it does not reflect on resuming the EditFriendsFragment. But strangely when I add checkmark to myself(including/excluding friends), the checkmark reflects correctly wherever applied. I guess there is some problem with the objectIds but I am not sure what it is.
Thanks, Ankit
Code from onResume() for EditFriendsFragment:
@Override
public void onResume() {
super.onResume();
// Choose multiple friends
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
mCurrentUser = ParseUser.getCurrentUser();
mFriendRelation = mCurrentUser.getRelation(ParseConstants.KEY_FRIENDS_RELATION);
// Activate progress indicator
getActivity().setProgressBarIndeterminateVisibility(true);
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.addAscendingOrder(ParseConstants.KEY_USERNAME);
query.setLimit(ParseConstants.MAX_USER_LIMIT);
query.findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> users, ParseException e) {
// Deactivate progress indicator
getActivity().setProgressBarIndeterminateVisibility(false);
final Map<ParseUser, Boolean> usersMap = new HashMap<ParseUser, Boolean>();
if (e == null) {
mUsers = users;
// Put all users in HashMap
for (ParseUser user : mUsers) {
usersMap.put(user, false);
}
// Log details
for (Map.Entry<ParseUser, Boolean> user : usersMap.entrySet()) {
Log.i(TAG, "User: " + user.getKey().getUsername() + " " + "Friend: " + user.getValue());
}
final String[] usernames = new String[mUsers.size()];
int i = 0;
for (ParseUser user : mUsers) {
usernames[i] = user.getUsername();
i++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_checked, usernames);
setListAdapter(adapter);
//addFriendsCheckmark();
// Set a boolean for matching friends
mFriendRelation.getQuery().findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> friends, ParseException e) {
if (e == null) {
Log.i(TAG, "Friends List size: " + friends.size());
for (ParseUser friend : friends) {
Log.i(TAG, "Friend: " + friend.getUsername());
}
for (ParseUser friend : mUsers) {
Log.i(TAG, "mUser Friend: " + friend.getUsername());
}
int i = 0;
for (ParseUser friend : friends) {
ParseUser user = mUsers.get(i);
if ((friend.getObjectId()).equals(user.getObjectId())) {
Log.i(TAG, "Switch boolean for " + friend.getUsername() + " Id: " + friend.getObjectId());
usersMap.put(friend, true);
}
i++;
}
// Log details
for (Map.Entry<ParseUser, Boolean> user : usersMap.entrySet()) {
Log.i(TAG, "[In Background] User: " + user.getKey().getUsername() + " " + "Friend: " + user.getValue());
}
// Add checkmark to friends
for (Map.Entry<ParseUser, Boolean> user : usersMap.entrySet()) {
if (user.getValue()) {
String username = user.getKey().getUsername();
getListView().setItemChecked(Arrays.asList(usernames).indexOf(username), true);
}
}
}
else {
Log.e(TAG, e.getMessage());
}
}
});
}
else {
Log.e(TAG, e.getMessage());
// Display error message
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(e.getMessage());
builder.setTitle(R.string.error_title);
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
}
1 Answer
Ben Jakuben
Treehouse TeacherI think this is your trouble spot:
int i = 0;
for (ParseUser friend : friends) {
ParseUser user = mUsers.get(i);
if ((friend.getObjectId()).equals(user.getObjectId())) {
Log.i(TAG, "Switch boolean for " + friend.getUsername() + " Id: " + friend.getObjectId());
usersMap.put(friend, true);
}
i++;
}
I added this statement before the if block to see what was going on:
Log.i(TAG, "friend ID: " + friend.getObjectId() + " || user ID: " + user.getObjectId());
That made me realize you're looping through friends and mUsers at the same time. So you still aren't checking each friend against each user or vice versa.
I'm glad you're trying to optimize this, though. I wasn't thrilled with this approach, but it seemed the simplest method to explain without getting into Big O Notation or other things I thought were beyond the scope of this course. I had a different solution somewhere...I'll see if I can find it. Let us know in here if you modify your approach. :)
Ankit B
4,180 PointsAnkit B
4,180 PointsThanks Ben! I did not realize that earlier; I re-thought the whole process..finally, I fixed it :)