屏幕旋转后保留片段

时间:2019-10-28 12:44:19

标签: java android android-fragments screen-orientation

我认为stackoverflow已经有很多这样的话题,但是我还是听不懂。

问题是,当屏幕旋转且互联网不活动时,我想保留片段及其数据。

所以情况是:

  1. 加载主要活动
  2. 关闭互联网
  3. 旋转屏幕
  4. 检查数据是否仍然存在

我的代码的问题是,当用户旋转屏幕并且互联网处于不活动状态时,它将无法加载,因为据我所知它将在View Model中调用setShow(),这将使API失效。

我不允许使用类似android:configChange或setRetainInstance之类的东西。只要 类似于onSaveInstanceState。

这是我的MainActivity.java:

public class MainActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener {

    private Fragment pageContent;

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

        BottomNavigationView navigation = findViewById(R.id.navigation);

        navigation.setOnNavigationItemSelectedListener(this);

        if (savedInstanceState == null) {
            navigation.setSelectedItemId(R.id.navigation_movies);
        } else {
            pageContent = getSupportFragmentManager().getFragment(savedInstanceState, "fragment");

            loadFragment(pageContent);
        }
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        Fragment fragment = null;

        switch (menuItem.getItemId()) {
            case R.id.navigation_movies:
                Bundle movieBundle = new Bundle();
                movieBundle.putBoolean("isFavorite", false);
                fragment = new MovieFragment();
                fragment.setArguments(movieBundle);
                pageContent = fragment;
                break;
            case R.id.navigation_tvshow:
                Bundle tvBundle = new Bundle();
                tvBundle.putBoolean("isFavorite", false);
                fragment = new TvShowFragment();
                fragment.setArguments(tvBundle);
                pageContent = fragment;
                break;
        }
        return loadFragment(fragment);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        getSupportFragmentManager()
                .putFragment(outState, "fragment", pageContent);
    }

    private boolean loadFragment(Fragment fragment) {
        if (fragment != null) {
            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.frame_container, fragment)
                    .commit();
            return true;
        }

        return false;
    }
}

MovieFragment.java(与TvShowFragment相同)。

public class MovieFragment extends Fragment {

    private ShowAdapter adapter;
    private ProgressBar progressBar;
    private ShowViewModel showViewModel;
    private FavoriteHelper favoriteHelper;
    private Boolean isFavorite;

    public MovieFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getActivity() != null) {
            showViewModel = ViewModelProviders.of(getActivity()).get(ShowViewModel.class);
            showViewModel.getShows().observe(this, getShow);
        }
    }

    private Observer<ArrayList<Show>> getShow = new Observer<ArrayList<Show>>() {
        @Override
        public void onChanged(ArrayList<Show> shows) {
            if (shows != null) {
                adapter.setData(shows);
                showLoading(false);
            }
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        Bundle bundle = getArguments();
        this.isFavorite = bundle.getBoolean("isFavorite");
        return inflater.inflate(R.layout.fragment_show, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        progressBar = view.findViewById(R.id.progressBar);
        showLoading(true);

        adapter = new ShowAdapter();
        adapter.notifyDataSetChanged();

        favoriteHelper = FavoriteHelper.getInstance(getActivity());

        RecyclerView recyclerView = view.findViewById(R.id.rv_show);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setAdapter(adapter);

        showViewModel.setShows("movie");
    }

    private void showLoading(Boolean state) {
        if (state) {
            progressBar.setVisibility(View.VISIBLE);
        } else {
            progressBar.setVisibility(View.GONE);
        }
    }
}

和ShowViewModel.java

public class ShowViewModel extends ViewModel {
    private static final String API_KEY = "API_KEY";
    private MutableLiveData<ArrayList<Show>> listShows = new MutableLiveData<>();
    private AsyncHttpClient client = new AsyncHttpClient();
    private ArrayList<Show> listItems = new ArrayList<>();
    private Show show;

    public void setShows(final String type) {
        listItems.clear();
        String url = String.format("https://api.themoviedb.org/3/discover/%s?api_key=%s&language=en-US", type, API_KEY);

        client.get(url, new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                try {
                    String result = new String(responseBody);
                    JSONObject responseObject = new JSONObject(result);
                    JSONArray results = responseObject.getJSONArray("results");

                    for (int i = 0; i < results.length(); i++) {
                        JSONObject shows = results.getJSONObject(i);
                        Show show = new Show();
                        show.setTitle(shows.getString(type.equals("movie") ? "title" : "name"));
                        show.setImage(shows.getString("poster_path"));
                        show.setBackdropImage(shows.getString("backdrop_path"));
                        show.setSynopsis(shows.getString("overview"));
                        show.setRelease(shows.getString(type.equals("movie") ? "release_date" : "first_air_date"));
                        listItems.add(show);
                    }
                    listShows.postValue(listItems);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                Log.d("onFailure", error.getMessage());
            }
        });
    }

    public LiveData<ArrayList<Show>> getShows() {
        return listShows;
    }
}

有什么想法吗?谢谢。

1 个答案:

答案 0 :(得分:0)

创建一个BaseActivity,然后保留savedInstanceState。 例子:

public class BaseActivity extends AppCompatActivity {

protected Bundle savedInstanceState;

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

并从您的活动类扩展此BaseActivity,然后检查父级saveInstanceState是否为null。例子:

public class MainActivity extends BaseActivity implements BottomNavigationView.OnNavigationItemSelectedListener {

private Fragment pageContent;

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

    BottomNavigationView navigation = findViewById(R.id.navigation);

    navigation.setOnNavigationItemSelectedListener(this);

    if (savedInstanceState != null) {
        pageContent = getSupportFragmentManager().getFragment(savedInstanceState, "fragment");
    }
    else {
        // load your fragment..
    }

}

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
    Fragment fragment = null;

    switch (menuItem.getItemId()) {
        case R.id.navigation_movies:
            Bundle movieBundle = new Bundle();
            movieBundle.putBoolean("isFavorite", false);
            fragment = new MovieFragment();
            fragment.setArguments(movieBundle);
            pageContent = fragment;
            break;
        case R.id.navigation_tvshow:
            Bundle tvBundle = new Bundle();
            tvBundle.putBoolean("isFavorite", false);
            fragment = new TvShowFragment();
            fragment.setArguments(tvBundle);
            pageContent = fragment;
            break;
    }
    return loadFragment(fragment);
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager()
            .putFragment(outState, "fragment", pageContent);
}

private boolean loadFragment(Fragment fragment) {
    if (fragment != null) {
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.frame_container, fragment)
                .commit();
        return true;
    }

    return false;
}

}