How to take a JSON String and display in recyclerview without repeating?

Asked

Viewed 134 times

1

I have a json with a list of users, photos posted by this user. The idea is to have a recyclerview with the name of the users, and when clicked, it will display the photos of that user.

The structure is like this:

{
"stories": [
        {
            "story_id": 1,
            "username": "pedroGC",
            "imagem": "url1.jpg"
},
         {
            "story_id": 2,
            "username": "tiagoFB",
            "user_id": "url2.jpg"
},
         {
            "story_id": 3,
            "username": "pedroGC",
            "user_id": "url3.jpg"
         }
      ]

}

Doubt number 01:

Is there a way to capture usernames without repeating and displaying in recyclerview? Like, pedroGC appears twice in JSON, the idea is to display a list of users who have posted photos, so in this example would be displayed only pedroGB and tiaboFB in recyclerview.

Doubt number 02:

There is how to make an array of all user images clicked to be displayed, from recyclerview’s onclick?

Example: If you click on the GC stone, join the two urls in an array (I created a "slider" that takes the photos from an array of strings, the problem is creating this array).

I already managed to display the 3 users in a recyclerview, and when clicked was displayed the photo, what I want, maybe it is something too complex, but it is to display only once the user, and when clicked, it takes all the objects that contain this user and make an array with the Strings.

The change must come from the adapter, model class, or Activity that will display the images?

1 answer

1


You can group the records according to one of the fields.

If you have 24+ minimum api, you can use streams:

List<Story> stories = Arrays.asList(
    new Story(1L, "pedroGC", "url1.jpg"),
    new Story(2L, "tiagoFB", "url2.jpg"),
    new Story(3L, "pedroGC", "url3.jpg")
);

Map<String, List<Story>> groupedByStream = stories
    .stream()
    .collect(Collectors.groupingBy(it -> it.username));

Otherwise, you can use a lib or do it in your hand:

public Map<String, List<Story>> groupByUsername(List<Story> stories) {
  Map<String, List<Story>> output = new HashMap<>();

  for (Story story : stories) {
    String nome = story.username;

    List<Story> userStories;
    if(output.containsKey(nome)) {
      userStories = output.get(nome);
    } else {
      userStories = new ArrayList<>();
    }

    userStories.add(story);
    output.put(nome, userStories);

  return grouped;

}
...
...
Map<String, List<Story>> customGroup = groupByUsername(stories);

This way you will have a Map where the keys are the names of the users and the values are the Stories of each user.

The downside is that to list users in a recyclerview, you will need to access the map keys through an index. But you can create a list with the keys.

The Adapter would look something like this:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

  List<String> usersByIndex;
  Map<String, List<Story>> groupedStories;


  public MyAdapter(Map<String, List<Story>> groupedStories) {
    this.groupedStories = groupedStories;
    this.usersByIndex = new ArrayList<>(groupedStories.keySet());
  }

  @Override
  public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    ...
  }

  @Override
  public void onBindViewHolder(MyViewHolder holder, int position) {
    // Pego o nome do usuário pelo index do adapter
    String username = usersByIndex.get(position);

    // Pego as stories pelo nome do usuário
    List<Story> userStories = groupedStories.get(username);

    holder.setUserStories(username, userStories);
  }

  @Override
  public int getItemCount() {
    return usersByIndex.size();
  }

  public class MyViewHolder extends RecyclerView.ViewHolder {

    ...

    public void setUserStories(String username, List<Story> userStories) {
        // Dentro do ViewHolder tenho acesso ao username e aos stories
    }

  }

  ...
}
  • Man, you’re a genius! After receiving from my teacher a "this is not possible, you will have to redo the server-side api" I was already getting discouraged with the project, but you not only showed me the way, but you gave me a Colletions lesson. Thank you very much! I made the adaptations of Adapter to my code, and the only problem I’m facing is to access the list of Stories of each user by onclick, is already appearing only 2 users in recyclerview, but when I click, shows only the first photo posted by them. But I think that’s my Model class problem.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.