Логика структуры списка для отображения в Recyclerview

#android #arraylist #android-recyclerview

#Android #arraylist #android-recyclerview

Вопрос:

У меня есть массив JSON, который необходимо проанализировать таким образом, чтобы он был похож на прилагаемый скриншот. Так, например, массив JSON будет приведен ниже, и он содержит шесть элементов, которые необходимо проанализировать с помощью цикла, но не может создать правильную структуру данных. Существуют разные уровни, и если у дочерних элементов есть общий родительский элемент, ему необходимо управлять только этим родительским идентификатором. Для уровня 1 не будет родительского идентификатора

Массив JSON

 "clubSubAreas":[
{
"id":573801,
"clubId":16733,
"areaId":58482,
"name":"subcoach c2a",
"level":4,
"parentId":569125,
"clubMemberSubAreas":{}
},
{
"id":569114,
"clubId":16733,
"areaId":53279,
"name":"Hockey",
"level":1,
"parentId":null,
"clubMemberSubAreas":{}
},
{
"id":569122,
"clubId":16733,
"areaId":53280,
"name":"Team H2",
"level":2,
"parentId":569114,
"clubMemberSubAreas":{}
},
{
"id":569131,
"clubId":16733,
"areaId":53281,
"name":"Coach H2",
"level":3,
"parentId":569122,
"clubMemberSubAreas":{}
},
{
"id":569119,
"clubId":16733,
"areaId":53280,
"name":"Team F2",
"level":2,
"parentId":569112,
"clubMemberSubAreas":{}
},
{
"id":569127,
"clubId":16733,
"areaId":53281,
"name":"Coach F1",
"level":3,
"parentId":569118,
"clubMemberSubAreas":{}
},
{
"id":569851,
"clubId":16733,
"areaId":58482,
"name":"sub coach f1",
"level":4,
"parentId":569127,
"clubMemberSubAreas":{}
},
{
"id":569112,
"clubId":16733,
"areaId":53279,
"name":"Football",
"level":1,
"parentId":null,
"clubMemberSubAreas":{}
},
{
"id":569118,
"clubId":16733,
"areaId":53280,
"name":"Team F1",
"level":2,
"parentId":569112,
"clubMemberSubAreas":{}
},
{
"id":569716,
"clubId":16733,
"areaId":58482,
"name":"subcoasch c2",
"level":4,
"parentId":569125,
"clubMemberSubAreas":{}
},
{
"id":569125,
"clubId":16733,
"areaId":53281,
"name":"Coach C2",
"level":3,
"parentId":569116,
"clubMemberSubAreas":{}
},
{
"id":569116,
"clubId":16733,
"areaId":53280,
"name":"Team C2",
"level":2,
"parentId":569113,
"clubMemberSubAreas":{}
},
{
"id":573787,
"clubId":16733,
"areaId":58482,
"name":"subcoach c2 new",
"level":4,
"parentId":573786,
"clubMemberSubAreas":{}
},
{
"id":573786,
"clubId":16733,
"areaId":53281,
"name":"Coach C2 new",
"level":3,
"parentId":569116,
"clubMemberSubAreas":{}
},
{
"id":569113,
"clubId":16733,
"areaId":53279,
"name":"Cricket",
"level":1,
"parentId":null,
"clubMemberSubAreas":{}
}
]
  

По сути, я хочу показать данные в представлении recycler, но не могу создать структуру данных с помощью ArrayList / Hashmap / TreeMap из заданного ответа JSON

Моя работа:

  ArrayList<ClubSubArea> clubSubAreaDept = new ArrayList<>();
        ArrayList<ClubSubArea> clubSubAreaSubDept = new ArrayList<>();
        ArrayList<ClubSubArea> clubSubAreaFunc = new ArrayList<>();
        ArrayList<ClubSubArea> clubSubAreaLevelFour = new ArrayList<>();
        for (ClubSubArea clubSubArea : clubMemberDataEdit.getClubSubAreas()) {
            if (clubSubArea.getLevel() == 1) {
                clubSubAreaDept.add(clubSubArea);
            } else if (clubSubArea.getLevel() == 2) {
                clubSubAreaSubDept.add(clubSubArea);
            } else if (clubSubArea.getLevel() == 3) {
                clubSubAreaFunc.add(clubSubArea);
            } else {
                clubSubAreaLevelFour.add(clubSubArea);
            }
        }
        ArrayList<ClubAreaCombine> clubAreaCombines1 = new ArrayList<>();
        ArrayList<ClubAreaCombine> clubAreaCombines = new ArrayList<>();
        if (clubAreas != null amp;amp; clubAreas.size() > 0) {
            for (ClubSubArea clubSubAreaDepartment : clubSubAreaDept) {
                for (ClubSubArea clubSubAreaSubDepartment : clubSubAreaSubDept) {
                    if (clubSubAreaSubDepartment.getParentId() == clubSubAreaDepartment.getId()) {
                        for (ClubSubArea clubSubAreaFunction : clubSubAreaFunc) {
                            if (clubSubAreaFunction.getParentId() == clubSubAreaSubDepartment.getId()) {

                                if (clubSubAreaLevelFour != null amp;amp; clubSubAreaLevelFour.size() > 0) {
                                    for (ClubSubArea clubSubAreaLFour : clubSubAreaLevelFour) {
                                        if (clubSubAreaLFour.getParentId() == clubSubAreaFunction.getId()) {
                                            ClubAreaCombine clubAreaCombine = new ClubAreaCombine(clubSubAreaDepartment,
                                                    clubSubAreaSubDepartment,
                                                    clubSubAreaFunction,
                                                    clubSubAreaLFour);
                                            clubAreaCombines1.add(clubAreaCombine);
                                        } else {
                                            ClubAreaCombine clubAreaCombine = new ClubAreaCombine(clubSubAreaDepartment,
                                                    clubSubAreaSubDepartment,
                                                    clubSubAreaFunction, null);
                                            clubAreaCombines1.add(clubAreaCombine);
                                        }
                                    }

                                } else {
                                    ClubAreaCombine clubAreaCombine = new ClubAreaCombine(clubSubAreaDepartment,
                                            clubSubAreaSubDepartment,
                                            clubSubAreaFunction,
                                            null);
                                    clubAreaCombines1.add(clubAreaCombine);
                                }
                            } else {
                                ClubAreaCombine clubAreaCombine = new ClubAreaCombine(clubSubAreaDepartment,
                                        clubSubAreaSubDepartment,
                                        null,
                                        null);
                                clubAreaCombines1.add(clubAreaCombine);
                            }
                        }
                    } else {
                        ClubAreaCombine clubAreaCombine = new ClubAreaCombine(clubSubAreaDepartment,
                                null,
                                null,
                                null);
                        clubAreaCombines1.add(clubAreaCombine);
                    }
                }
            }
        }



        for (ClubAreaCombine clubAreaCombine : clubAreaCombines1) {
            if (!clubAreaCombines.contains(clubAreaCombine)) {
                clubAreaCombines.add(clubAreaCombine);
            }
        }
  

ClubSubArea

 public class ClubSubArea implements Serializable {
    @SerializedName("id")
    private long id;
    @SerializedName("clubId")
    private Long clubId;
    @SerializedName("name")
    private String name;
    @SerializedName("level")
    private int level;
    @SerializedName("areaId")
    private Long areaId;
    @SerializedName("parentId")
    private Long parentId;
    @SerializedName("_links")
    List<Links> links;
    List<ClubSubArea> subAreaList = new ArrayList<>();
    @SerializedName("clubMemberSubAreas")
    ClubMemberSubAreas clubMemberSubAreas;




    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Long getClubId() {
        return clubId;
    }

    public void setClubId(Long clubId) {
        this.clubId = clubId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public Long getAreaId() {
        return areaId;
    }

    public void setAreaId(Long areaId) {
        this.areaId = areaId;
    }

    public Long getParentId() {
        return parentId;
    }

    public void setParentId(Long parentId) {
        this.parentId = parentId;
    }

    public List<Links> getLinks() {
        return links;
    }

    public void setLinks(List<Links> links) {
        this.links = links;
    }

    public List<ClubSubArea> getSubAreaList() {
        return subAreaList;
    }

    public void setSubAreaList(ArrayList<ClubSubArea> subAreaList) {
        this.subAreaList = subAreaList;
    }

    public ClubMemberSubAreas getClubMemberSubAreas() {
        return clubMemberSubAreas;
    }

    public void setClubMemberSubAreas(ClubMemberSubAreas clubMemberSubAreas) {
        this.clubMemberSubAreas = clubMemberSubAreas;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ClubSubArea that = (ClubSubArea) o;

        if (id != that.id) return false;
        if (level != that.level) return false;
        if (!clubId.equals(that.clubId)) return false;
        return parentId != null ? parentId.equals(that.parentId) : that.parentId == null;
    }

    @Override
    public int hashCode() {
        int result = (int) (id ^ (id >>> 32));
        result = 31 * result   clubId.hashCode();
        result = 31 * result   level;
        result = 31 * result   (parentId != null ? parentId.hashCode() : 0);
        return resu<
    }
}
  

Данные, отображаемые в Интернете следующим образом

введите описание изображения здесь

Комментарии:

1. Покажите свою работу, пожалуйста.

2. @IntelliJAmiya добавил мою работу

Ответ №1:

Попробуйте следующее. Я не тестировал его, поэтому, возможно, есть некоторые ошибки. (Я изменил ваш ClubSubArea, чтобы все поля были общедоступными, чтобы не нужно было использовать геттеры / сеттеры)

 class CrazyMapper {

    List<RowItem> map(List<ClubSubArea> items) {
        // We return an empty list if there is no items.
        if (items.size() == 0) {
            return new ArrayList<>();
        }

        // We create a list with all the last elements (the ones not used as parent)
        List<ClubSubArea> children = new ArrayList<>();
        for (ClubSubArea club : items) {
            if (isChild(club, items)) {
                children.add(club);
            }
        }

        // Then we remove all the children ClubSubArea from the items list
        items.removeAll(children);

        // Now we want to build each row.
        // Each row is a list of ClubSubArea. In your example, one will be Cricket, then Team, then Captain...
        // We want them in that order. According to your Json, the Coach is the one with the level max,
        // then the Captain, then the Team, then Cricket.
        // Cricket has no parent but otherwise, Coach has Captain id as a parent, and Captain has
        // Teams id as a parent.
        // With buildRowList we gonna create the list in that order (Cricket, Team,...) using the parent id.
        List<RowItem> rowItems = new ArrayList<>();
        for (ClubSubArea club : children) {
            List<ClubSubArea> result = new ArrayList<>();
            result.add(club);
            buildRowList(items, club, result);
            rowItems.add(new RowItem(result));
        }

        return rowItems;
    }

    // Check if the item is used as parent in another one in the list. If not, it's the last
    // element (child).
    private boolean isChild(ClubSubArea item, List<ClubSubArea> items) {
        for (ClubSubArea club : items) {
            if (club.parentId == item.id) {
                return false;
            }
        }
        return true;
    }

    // This method is recursive (it calls itself until it can't (parent id is null)).
    private void buildRowList(List<ClubSubArea> list, ClubSubArea current, List<ClubSubArea> result) {
        for (ClubSubArea club : list) {
            if (club.id == current.parentId) {
                // We add the parent at index 0 in order to have the list starting with the highest
                // parent (parent with no parent id (should be the one with level 1))
                result.add(0, club);
                if (club.parentId != null) {
                    // We try to find the parent's parent.
                    buildRowList(list, club, result);
                }
                // We don't want to continue to loop if we found the parent
                return;
            }
        }
    }
}

// This is the class used by the adapter. The adapter will handle a list of RowItem.
class RowItem {
    public RowItem(List<ClubSubArea> items) {
        this.items = items;
    }

    List<ClubSubArea> items;
}
  

Комментарии:

1. Он отлично работает, если уровней четыре, но в сценарии, когда уровней меньше четырех, для этого не создается строка. Например, у меня есть данные до трех уровней, таких как футбол, команда F1 и капитан F1, тогда для этого не создается строка

2. Смешаны ли данные с максимальным значением 3 и данные с максимальным значением 4?

3. Да, это может зависеть от пользователя, для скольких уровней он хочет добавить данные. Предположим, что он добавил Cricket, тогда максимальный уровень будет равен 1, а если он добавит Cricket, Team1, тогда максимальный уровень будет равен 2, и так далее…

4. @Salmankhan Я обновил вышесказанное. Теперь RowItem будет содержать список разного размера в зависимости от того, что выбрал пользователь

5. Чертовски логичный человек. Большое вам спасибо, теперь он работает отлично. Еще раз большое спасибо.