我使用android java编程语言创建了一个Movie应用程序,使用API从TMDB提取的数据,一切都很好,并且按我的预期工作,但是问题是当屏幕旋转时,一次又一次地重新加载数据,我正在跟踪该网站上的一些教程,但仍然无法正常工作。
我正在跟踪以下链接:How to save an Android Activity state using save instance state?,但是我无法弄清楚本教程要针对我的情况实施
// this is my Movie Fragment
package com.ogi.layarkacamobile.fragment;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import com.ogi.layarkacamobile.MainActivity;
import com.ogi.layarkacamobile.R;
import com.ogi.layarkacamobile.adapter.MoviesAdapter;
import com.ogi.layarkacamobile.api.Client;
import com.ogi.layarkacamobile.api.Service;
import com.ogi.layarkacamobile.model.movie.MovieData;
import com.ogi.layarkacamobile.model.movie.MoviesResponse;
import com.ogi.layarkacamobile.util.PaginationScrollListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* A simple {@link Fragment} subclass.
*/
public class MoviesFragment extends Fragment {
private static final String TAG = "MoviesFragment";
RecyclerView rvMoviesList;
ProgressBar pbMovies;
MoviesAdapter moviesAdapter;
LinearLayoutManager linearLayoutManager;
private static final int PAGE_START = 1;
private boolean isLoading = false;
private boolean isLastPage = false;
private int TOTAL_PAGES = 10;
private int currentPage = PAGE_START;
private Service movieService;
public MoviesFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View layout = LayoutInflater.from(getContext()).inflate(R.layout.fragment_movies, container, false);
rvMoviesList = layout.findViewById(R.id.rv_movies_id);
pbMovies = layout.findViewById(R.id.pb_movies_id);
moviesAdapter = new MoviesAdapter(getContext());
linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
rvMoviesList.setLayoutManager(linearLayoutManager);
rvMoviesList.setItemAnimator(new DefaultItemAnimator());
rvMoviesList.setAdapter(moviesAdapter);
rvMoviesList.addOnScrollListener(new PaginationScrollListener(linearLayoutManager) {
@Override
protected void loadMoreItems() {
isLoading = true;
currentPage += 1;
// mocking network delay for API call
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
loadNextPage();
}
}, 1000);
}
@Override
public int getTotalPageCount() {
return TOTAL_PAGES;
}
@Override
public boolean isLastPage() {
return isLastPage;
}
@Override
public boolean isLoading() {
return isLoading;
}
});
// init service and load data
movieService = Client.getClient().create(Service.class);
loadFirstPage();
return layout;
}
private void loadFirstPage() {
Log.d(TAG, "LoadFirstPage");
callPopularMovieApi()
.enqueue(new Callback<MoviesResponse>() {
@Override
public void onResponse(Call<MoviesResponse> call, Response<MoviesResponse> response) {
// Got data send into adapter
List<MovieData> results = fetchResults(response);
pbMovies.setVisibility(View.GONE);
moviesAdapter.addAll(results);
if (currentPage <= TOTAL_PAGES) moviesAdapter.addLoadingFooter();
else isLastPage = true;
}
@Override
public void onFailure(Call<MoviesResponse> call, Throwable t) {
t.printStackTrace();
}
});
}
private List<MovieData> fetchResults(Response<MoviesResponse> response) {
MoviesResponse popularMovies = response.body();
return popularMovies.getResults();
}
private void loadNextPage() {
Log.d(TAG, "loadNextPage "+ currentPage);
callPopularMovieApi()
.enqueue(new Callback<MoviesResponse>() {
@Override
public void onResponse(Call<MoviesResponse> call, Response<MoviesResponse> response) {
moviesAdapter.removeLoadingFooter();
isLoading = false;
List<MovieData> results = fetchResults(response);
moviesAdapter.addAll(results);
if (currentPage != TOTAL_PAGES)moviesAdapter.addLoadingFooter();
else isLastPage = true;
}
@Override
public void onFailure(Call<MoviesResponse> call, Throwable t) {
t.printStackTrace();
}
});
}
private Call<MoviesResponse> callPopularMovieApi() {
return movieService.getPopularMovies("f6602517b834e9ce06a48548f949e397", currentPage);
}
}
这是我的MainActivity
package com.ogi.layarkacamobile;
import android.content.Intent;
import android.provider.Settings;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import com.ogi.layarkacamobile.adapter.ViewPagerAdapter;
import com.ogi.layarkacamobile.fragment.MoviesFragment;
import com.ogi.layarkacamobile.fragment.TvShowsFragment;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ViewPager viewPager = findViewById(R.id.viewpager);
setupViewPager(viewPager);
TabLayout tabLayout = findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new MoviesFragment(), getResources().getString(R.string.movies_label));
adapter.addFragment(new TvShowsFragment(), getResources().getString(R.string.tv_shows_label));
viewPager.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.language_setting) {
Intent mIntent = new Intent(Settings.ACTION_LOCALE_SETTINGS);
startActivity(mIntent);
}
return super.onOptionsItemSelected(item);
}
}
我正在尝试有关类似问题的建议,但没有一个可行,因为我不知道如何在我的情况下实施该问题,非常感谢您
答案 0 :(得分:1)
片段:
您正在使用片段。因此,防止方向发生破坏时可以使用setRetainInstance(true)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// retain this fragment when activity is re-initialized
setRetainInstance(true);
}
活动:
发生方向改变时,android重新启动正在运行的Activity(调用onDestroy()
,然后调用onCreate()
)。
如果要处理内部活动,则不能在清单文件中使用:进行特定活动。
对于API 12及以下版本:
android:configChanges="orientation"
如果您定位的是API 13或更高版本
android:configChanges="orientation|screenSize"
更新:在方向更改时保存片段状态
如果要在活动内部使用onSaveInstanceState
保存片段状态,则可以使用putFragment
。
在您的活动中,onSaveInstanceState
如下所示:
@Override
protected void onSaveInstanceState(Bundle outState) {
getFragmentManager().putFragment(outState, MyFragment.TAG, mMyFragment);
}
要在活动重启后获取片段状态,可以使用getFragment
方法。
@Override
protected void onRestoreInstanceState(Bundle inState) {
FragmentTransaction transaction =getFragmentManager().beginTransaction();
if (inState != null) {
mMyFragment = (MyFragment) getFragmentManager().getFragment(inState, MyFragment.TAG);
} else {
mMyFragment = new MyFragment();
transaction.add(R.id.fragment, mMyFragment, MyFragment.TAG);
transaction.commit();
}
}
答案 1 :(得分:0)
使用LiveData。旋转设备时,它将缓存您的Recyclerview数据并从内部缓存中重新加载数据。