一个片段内的多个customViews的SavedInstance

时间:2018-09-24 14:04:48

标签: android android-fragments android-recyclerview

我在一个片段中有同一个CustomView的多个实例。 我为此CustomView实现了saveInstance,但是问题是因为该CustomView有多个实例,最后一个的savedInstance会覆盖所有实例。

例如,如果此CustomView的3个实例在其中包含recyclerview,则如果我滚动最后一个实例,它将应用于所有实例。因为我使用的是键值对,并且所有键都相同。 (我可以将密钥更改为每个密钥,但我认为有更好的方法)

这是在我的CustomView中保存和还原saveInstance的代码:

 @Nullable
@Override
protected Parcelable onSaveInstanceState() {
    Bundle bundle = new Bundle();
    bundle.putParcelable(SavedInstanceKey.SUPERSTATE.name(), super.onSaveInstanceState());
    bundle.putParcelable(SavedInstanceKey.RECYCLERVIEW.name(), recyclerView.getLayoutManager().onSaveInstanceState()); // ... save stuff
    return bundle;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
    if (state instanceof Bundle) // implicit null check
    {
        Bundle bundle = (Bundle) state;
        this.recyclerView.getLayoutManager().onRestoreInstanceState(bundle.getParcelable(SavedInstanceKey.RECYCLERVIEW.name())); // ... load stuff
        state = bundle.getParcelable(SavedInstanceKey.SUPERSTATE.name());
    }
    super.onRestoreInstanceState(state);
}

这是我片段的OnCreateView:

  @Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_artist, container, false);

    final GridListView gv_new = view.findViewById(R.id.gridlist_new_songs);
    final GridListView gv_best = view.findViewById(R.id.gridlist_best);
    final GridListView gv_singles = view.findViewById(R.id.gridlist_singles);
    final GridListView gv_feats = view.findViewById(R.id.gridlist_feats);
    final RecyclerView rc_albums = view.findViewById(R.id.rcview_album);

    if(!alreadyInitialized) {
        alreadyInitialized = true;
        apiService = new ApiService(getContext());
        try {
            artistID = getArguments().getString(KeyIntent.ARTIST.name());
        } catch (Exception e) {
            Log.e(TAG, "onCreateView: Artist Fragment doesnt have args.\t", e);
        }

        apiService.getArtist(artistID, new ApiService.OnArtistReceived() {
            @Override
            public void onSuccess(Artist artist) {
                ArtistFragment.this.artist=artist;
                setArtistToViews(artist, view);
            }

            @Override
            public void onFail() {
                Toast.makeText(getContext(), "Error on receiving artist.", Toast.LENGTH_LONG).show();
            }
        });

        apiService.getNewSongs(artistID, new ApiService.OnSongsReceived() {
            @Override
            public void onSuccess(List<Song> songs) {
                ArtistFragment.this.newSongs=songs;
                List<GridListable> gridListables = new ArrayList<>();
                gridListables.addAll(songs);
                gv_new.load(gridListables, 1);
            }

            @Override
            public void onFail(ApiService.ApiResponse response) {
                Toast.makeText(getContext(), "Error on receiving artist.", Toast.LENGTH_LONG).show();
            }
        });

        apiService.getBestSongs(artistID, new ApiService.OnSongsReceived() {
            @Override
            public void onSuccess(List<Song> songs) {
                ArtistFragment.this.bestSongs=songs;
                List<GridListable> gridListables = new ArrayList<>();
                gridListables.addAll(songs);
                gv_best.load(gridListables, 1);
            }

            @Override
            public void onFail(ApiService.ApiResponse response) {
                Toast.makeText(getContext(), "Error on receiving artist.", Toast.LENGTH_LONG).show();
            }
        });

        apiService.getSingleSongs(artistID, new ApiService.OnSongsReceived() {
            @Override
            public void onSuccess(List<Song> songs) {
                ArtistFragment.this.singleSongs=songs;
                List<GridListable> gridListables = new ArrayList<>();
                gridListables.addAll(songs);
                gv_singles.load(gridListables, 1);
            }

            @Override
            public void onFail(ApiService.ApiResponse response) {

            }
        });

        apiService.getFeats(artistID, new ApiService.OnSongsReceived() {
            @Override
            public void onSuccess(List<Song> songs) {
                ArtistFragment.this.feats=songs;
                List<GridListable> gridListables = new ArrayList<>();
                gridListables.addAll(songs);
                gv_feats.load(gridListables, 1);
            }

            @Override
            public void onFail(ApiService.ApiResponse response) {

            }
        });

        apiService.getAlbums(artistID, new ApiService.OnAlbumsReceived() {
            @Override
            public void onSuccess(List<Album> albums) {
                ArtistFragment.this.albums=albums;

                List<Projective> projectives = new ArrayList<>();
                projectives.addAll(albums);
                rc_albums.setAdapter(new AlbumAdapter(getContext(), projectives));
                rc_albums.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, true));
            }

            @Override
            public void onFail(ApiService.ApiResponse response) {
                Toast.makeText(getContext(), "Loading albums failed.", Toast.LENGTH_SHORT).show();
            }
        });
    }else {
        Log.i(TAG, "onCreateView: Fragment already initialized, restoring from existing artist");
        setArtistToViews(artist,view);
        gv_new.load(new ArrayList<>(newSongs),1);
        gv_best.load(new ArrayList<>(bestSongs),1);
        gv_singles.load(new ArrayList<>(singleSongs),1);
        gv_feats.load(new ArrayList<>(feats),1);
        rc_albums.setAdapter(new AlbumAdapter(getContext(), new ArrayList<>(albums)));
        rc_albums.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, true));
    }
    return view;
}

1 个答案:

答案 0 :(得分:0)

我认为问题在于您用于捆绑软件的密钥。您的所有自定义视图实例都使用相同的SavedInstanceKey.SUPERSTATE.name()

您可以尝试让Fragment向每个自定义视图(BEST,NEW ...)传递不同的密钥。这样,您的每个GridView都有其自己的唯一键,可在saveInstanceState和restoreInstanceState方法中使用。