0

This is an extension of Android implement Parcelable objects with hashmap that contains another hashmap where I was having trouble passing 2 classes between activities using Parcelable. I'm now able to successfully pass both classes together using Parcelable. However, I'm having trouble putting the retrieved data into an array list.

Here's the EventDetails class:

public class MatchedEvent implements Parcelable {

    Private String eventId;
    Private String eventName;
    Private Long eventUnixTime;
    Private Map <String, User> attendees = new HashMap<String, User>();

}

@Override
public void writeToParcel(Parcel dest, int flags) {

    dest.writeString(eventId);
    dest.writeString(eventName);
    dest.writeLong(eventUnixTime);
    final int N = attendees.size();
    dest.writeInt(N);
    if (N > 0) {
        for (Map.Entry<String, User> entry : attendees.entrySet()) {
            dest.writeString(entry.getKey());
            User user = entry.getValue();
            dest.writeString(user.getEmail());
            dest.writeString(user.getUserName());
            dest.writeString(user.getUserPicture());
        }
    }
}

protected MatchedEvent(Parcel in) {
    eventId = in.readString();
    eventName = in.readString();
    eventUnixTime = in.readLong();
    final int N = in.readInt();
    for (int i = 0; i < N; i++) {
        String key = in.readString();
        User user = new User();
        user.email = in.readString();
        user.userName = in.readString();
        user.userPicture = in.readString();
        attendees.put(key, user);
    }
}


public Map<String, User> getAttendees() {
  return attendees;
}

Here's the User class:

public class User implements Parcelable {

    public String email;
    public String userName;
    public String userPicture;
    private Boolean hasLoggedInWithPassword;
    private HashMap<String, Object> dateJoined = null;
}

public User(Parcel in) {
    email = in.readString();
    userName = in.readString();
    userPicture = in.readString();
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(email);
    dest.writeString(userName);
    dest.writeString(userPicture);
}

Here's the Fragment to retrieve the data. The EventDetails class should return a few Users. My goal is to display the name of all Users in a TextView that lists out the names with a line break. I was able to retrieve the users in an array but was not able to create an array just for the userName.

public class EventDetailsFragment extends BaseFragment {


    TextView attendees;

    private Map<String, User> attendeeMap;

      @Override
      public void onCreate(Bundle savedInstanceState) {

      MatchedEvent matchedEvent = getArguments().getParcelable("eventDetailsData");

      attendeesMap = matchedEvent.getAttendees();

      List<User> users = new ArrayList<>();

      for (String key : attendeesMap.keySet()) {
      User user = attendeesMap.get(key);
      users.add(user);

      Log.i("Attendees Details", String.valueOf(user)); //I was able to get all users in this log.

      ArrayList<String> attendeesDetails = new ArrayList<>();
      attendeesDetails.add(user.getEmail());
      attendeesDetails.add(user.getUserName());
      attendeesDetails.add(user.getUserPicture());

        for (User user1 : users) {
          Log.i("Attendees Details", String.valueOf(attendeesDetails)); //?????????????????
        }
      }


}

The problem is where i put the mark "//?????????????????". I'm getting duplicate data. I know I shouldn't be putting a loop inside another loop. Can someone please advise how I can break this down? My goal is to put all the users' names in an array and display them in the TextView with a line break after each name.

This is what I got from the log:

I/Attendees Details: com.test.entities.User@f2b14s9
I/Attendees Details: [user1@gmail.com, Deric, https://dropbox.xxxxxx]
I/Attendees Details: com.test.entities.User@e6s26k2
I/Attendees Details: [user2@gmail.com, Jose, https://dropbox.xxxxxxxxx]
I/Attendees Details: [user2@gmail.com, Jose, https://dropbox.xxxxxxxxx]
I/Attendees Details: com.text.entities.User@b9k03l6
I/Attendees Details: [user3@gmail.com, Matt, https://dropbox.xxxxxxxxxxxxx]
I/Attendees Details: [user3@gmail.com, Matt, https://dropbox.xxxxxxxxxxxxx]
I/Attendees Details: [user3@gmail.com, Matt, https://dropbox.xxxxxxxxxxxxx]

I believe the reason why there are duplicate entries is because "attendeesDetails" is inside the loop “attendeesMap” where I got the key of each user. I’m not sure how to separate them but still able to get the data.

Thanks in advance for helping out.

-R

Community
  • 1
  • 1
runrmrf
  • 71
  • 2
  • 6
  • What do you mean "duplicate data" ? your `atendeesDetails` is an array list with email, username and picture in succession. I don't understand why you need it that way. – Martin Marconcini Apr 27 '17 at 22:58
  • I've added the results from the log. Do you know how to get the "name" of each user? – runrmrf Apr 28 '17 at 05:04
  • let me take another look. – Martin Marconcini Apr 28 '17 at 18:44
  • The way I did it was probably not efficient. It's my first time handling Parcelable. The MatchedEvent class is going to return multiple users. The goal here is to get each and every user's name to display on the TextView. Could you recommend any other ways to get this info from the Parcelable of those two classes (without looking at my code and forget about my nested 'for' loops)? – runrmrf Apr 28 '17 at 20:42
  • First I'd recommend you use Parceler library to deal with Parcel. (I've benchmarked it and it's performance penalty is less than 5% on an already super fast operation), but makes dealing with Parcelable a breeze. – Martin Marconcini Apr 28 '17 at 22:31
  • Is this data model (MatchedEvent) fixed or can you change the model? – Martin Marconcini Apr 28 '17 at 22:31
  • I think I found a solution to my problem and posted the answer. Thanks for looking into this @MartinMarconcini. – runrmrf Apr 29 '17 at 01:51

2 Answers2

0

this will help you:

              @Override
              public void onCreate(Bundle savedInstanceState) {

              EventDetails eventDetails = getArguments().getParcelable("eventDetailsData");

              attendeesMap = eventDetails.getAttendees();

              List<User> users = new ArrayList<>();

              for (String key : attendeesMap.keySet()) {
              User user = attendeesMap.get(key);
              users.add(user);

              Log.i("Attendees Details", String.valueOf(user)); //I was able to get all users in this log.

attendees.append(user.getEmail()+user.getUserName()+user.getUserPicture()+"\n");

              }
Mortada Jafar
  • 3,529
  • 1
  • 18
  • 33
  • Hi Mortadda, it's returning a "null" value. My goal is to display the name of each and every user. – runrmrf Apr 27 '17 at 23:47
0

I think I'd resolved the problem. I actually need to create an ArrayList<HashMap<String, String>> to store the details for each and every user first. Then, I'll be able to create another array list to store the names. No more nested loops.

List<User> users = new ArrayList<>();
ArrayList<HashMap<String, String>> userArrayList = new ArrayList<HashMap<String, String>>();
HashMap<String, String> usersDetailsHashMap = new HashMap<String, String>();
ArrayList attendeesNames = new ArrayList();

for (String key : attendeesMap.keySet()) {
    User user = attendeesMap.get(key);
    users.add(user);

    usersDetailsHashMap.put("name", user.getUserName());
    usersDetailsHashMap.put("email", user.getEmail());
    usersDetailsHashMap.put("picture", user.getUserPicture());

    userArrayList.add(usersDetailsHashMap);

    attendeesNames.add(userArrayList.get(0).get("name"));

}

Log.i("userNames", String.valueOf(attendeesNames));

This will return in the log:

[Deric, Jose, Matt]
runrmrf
  • 71
  • 2
  • 6