我认为stackoverflow已经有很多这样的话题,但是我还是听不懂。
问题是,当屏幕旋转且互联网不活动时,我想保留片段及其数据。
所以情况是:
我的代码的问题是,当用户旋转屏幕并且互联网处于不活动状态时,它将无法加载,因为据我所知它将在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;
}
}
有什么想法吗?谢谢。
答案 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;
}
}