Мне нужно реализовать parcelable в моем настраиваемом классе ArtistInfo со следующей структурой:

    public class ArtistInfo implements Parcelable {

    private String artist;

    // album name to list of ids of songs
    private HashMap> albumInfo;

    // song id to songInfo
    private SparseArray songsMap;

    protected ArtistInfo(Parcel in) {
        artist = in.readString();
    }

    public static final Creator CREATOR = new Creator() {
        @Override
        public ArtistInfo createFromParcel(Parcel in) {
            return new ArtistInfo(in);
        }

        @Override
        public ArtistInfo[] newArray(int size) {
            return new ArtistInfo[size];
        }
    };

    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public void addSongsInfoToAlbum(List songsInfo, String album) {
        if (albumInfo == null) {
            albumInfo = new HashMap();
        }

        if (songsMap == null) {
            songsMap = new SparseArray();
        }
        List songsIds = new ArrayList();
        for (SongInfo songInfo : songsInfo) {
            songsIds.add(songInfo.getId());
            songsMap.put(songInfo.getId(), songInfo);
        }
        List songsIdsForAlbum = getSongIdsForAlbum(album);
        songsIdsForAlbum.addAll(songsIds);
        albumInfo.put(album, songsIdsForAlbum);
    }

    private List getSongIdsForAlbum(String album) {
        if (albumInfo == null) {
            return new ArrayList();
        }

        List songsIds = albumInfo.get(album);
        return songsIds == null ? new ArrayList() : songsIds;
    }

    public HashMap> getAlbumInfo() {
        return albumInfo;
    }

    public SparseArray getSongsMap() {
        if (songsMap == null) {
            songsMap = new SparseArray();
        }
        return songsMap;
    }

    @Override
    public String toString() {
        return "ArtistInfo{" +
                "artist='" + artist + '\'' +
                ", albumInfo=" + albumInfo.toString() +
                ", songsMap=" + songsMap.toString() +
                '}';
    }

    @Override
    public int describeContents() {
        return 0;
    }

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

А ниже представлена ​​структура класса SongInfo, используемого в указанном выше классе:

public class SongInfo implements Parcelable {

    private Integer id;

    private String name;

    private String url;

    public SongInfo(Integer id, String name, String url) {
        this.id = id;
        this.name = name;
        this.url = url;
    }

    protected SongInfo(Parcel in) {
        if (in.readByte() == 0) {
            id = null;
        } else {
            id = in.readInt();
        }
        name = in.readString();
        url = in.readString();
    }

    public static final Creator CREATOR = new Creator() {
        @Override
        public SongInfo createFromParcel(Parcel in) {
            return new SongInfo(in);
        }

        @Override
        public SongInfo[] newArray(int size) {
            return new SongInfo[size];
        }
    };

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        if (id == null) {
            dest.writeByte((byte) 0);
        } else {
            dest.writeByte((byte) 1);
            dest.writeInt(id);
        }
        dest.writeString(name);
        dest.writeString(url);
    }
}

Теперь, как вы видите, нет проблем с реализацией интерфейса Parcelable в классе SongInfo, но я не могу понять, как читать и записывать переменные albumInfo и songsMap . в методе Constructor и writeToParcel соответственно. Может кто-нибудь, пожалуйста, помогите мне понять, как мне это сделать. Спасибо!

0
tom 16 Сен 2018 в 12:33

1 ответ

Лучший ответ

Идея состоит в том, чтобы перебрать каждый элемент в albumInfo и songsMap, а затем добавить его в Parcelable.

Пишите в посылку.

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(artist);

    // Write album info
    dest.writeInt(albumInfo.size());
    for (Map.Entry<String, List<Integer>> item : albumInfo.entrySet()) {
        dest.writeString(item.getKey());
        dest.writeList(item.getValue());
    }

    // Write song map
    dest.writeInt(songsMap.size());
    for (int i = 0; i < songsMap.size(); i++) {
        int key = songsMap.keyAt(i);
        dest.writeInt(key);
        dest.writeParcelable(songsMap.get(key), flags);
    }
}

Читать из посылки

protected ArtistInfo(Parcel in) {
    artist = in.readString();

    // Read album info
    albumInfo = new HashMap<>();
    int albumInfoSize = in.readInt();
    for (int i = 0; i < albumInfoSize; i++) {
        String key = in.readString();
        List<Integer> value = new ArrayList<>();
        in.readList(value, null);
        albumInfo.put(key, value);
    }

    // Read song map
    songsMap = new SparseArray<>();
    int songsMapSize = in.readInt();
    for (int i = 0; i < songsMapSize; i++) {
        int key = in.readInt();
        SongInfo value = in.readParcelable(SongInfo.class.getClassLoader());
        songsMap.put(key, value);
    }
}
1
Son Truong 16 Сен 2018 в 10:33