这个片段如何在旋转时保持状态

时间:2017-10-12 02:58:40

标签: android android-fragments rotation

我正在试验片段。我的MainActivity包含一个可以交换片段的framelayout(master" SearchFragment"以及详细信息" LyricsFragment"):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    FragmentManager fragmentManager = getSupportFragmentManager();

    int index = fragmentManager.getBackStackEntryCount() - 1;
    if (index == -1) {
        fragmentManager.beginTransaction()
                .replace(R.id.placeholder, new SearchFragment(), SEARCH)
                .commit();
    } else {
        FragmentManager.BackStackEntry backEntry = fragmentManager.getBackStackEntryAt(index);
        String tag = backEntry.getName();
        Fragment fragment = fragmentManager.findFragmentByTag(tag);
        if (fragment != null) {
            fragmentManager.beginTransaction()
                    .replace(R.id.placeholder, fragment)
                    .commit();
        }
    }
}

我使用https://github.com/frankiesardo/icepick将我的SearchFragment状态保存在arrayList:

public class SearchFragment extends Fragment {

    @Inject CompositeSubscription subscriptions;

    @BindView(R.id.search_field) EditText searchField;
    @BindView(R.id.recyclerview) RecyclerView recyclerView;

    @State ArrayList<Track> tracks = new ArrayList<>();
    private TrackAdapter adapter;
    private TrackClickListener listener;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof  TrackClickListener) {
            listener = (TrackClickListener) context;
        } else {
            throw new IllegalArgumentException("context must be of type TrackClickListener");
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_search, container, false);
        bindViews(view);

        adapter = new TrackAdapter(listener, picasso);
        recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), COLS));
        recyclerView.setAdapter(adapter);
        Log.d("TRACK", "tracks.size=" + tracks.size());
        adapter.setAdapterItems(tracks);
        return view;
    }

    @VisibleForTesting
    void onSearchSuccess(ArrayList<Track> tracks) {
        this.tracks = tracks;
        adapter.setAdapterItems(tracks);
    }

    @OnClick(R.id.search_button)
    void onSearchClick() {
        searchTracks();
    }

    private void searchTracks() {
        subscriptions.add(api.searchTracks(searchTerm)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<SearchResult>() {

                    @Override
                    public void onCompleted() {}
                    @Override
                    public void onError(Throwable e) {}

                    @Override
                    public void onNext(SearchResult searchResult) {
                        onSearchSuccess(searchResult.getResults());
                    }
                }));
    }

public interface TrackClickListener {
    void startDetailScreen(Track track);
}
}

有人可以解释为什么日志语句会在轮换时打印出来:

tracks.size = 20 ----旋转屏幕---- tracks.size = 20 tracks.size = 0

该列表最初保留,但最终被清除。旋转后如何保存填充的回收者视图?我使用的库避免了saveInstanceState的样板。我希望保存我的列表,并在旋转设备时使用它重置适配器。

1 个答案:

答案 0 :(得分:0)

你需要像Icepick那样存储/重新存储状态变量,

@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       Icepick.restoreInstanceState(this, savedInstanceState);
}

@Override protected void onSaveInstanceState(Bundle outState) {
       super.onSaveInstanceState(outState);
       Icepick.saveInstanceState(this, outState);
}