Reputation: 13
I had created a Movie app using android java programming language, the data taken from TMDB using an API, everything is fine and working as i expected, but the problem is data reloaded again and again when the screen rotated, i was following some tutorial from this website but still did not working.
i was following this link : How to save an Android Activity state using save instance state?, but i can't figuring out this tutorial to be implemented on my case
// 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);
}
}
And this is my 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);
}
}
I was trying the suggestion about the similar question but non of them working, because i do not know exactly how to implement that in my case, thank you so much in advanced
Upvotes: 0
Views: 1867
Reputation: 29867
Use LiveData. It will cache your Recyclerview data and reload it from internal cache when the device is rotated.
Upvotes: 0
Reputation: 862
Fragment :
You are using fragment.So prevent destroy on orientation change occurs to fragment you can use setRetainInstance(true)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// retain this fragment when activity is re-initialized
setRetainInstance(true);
}
Activity:
When orientaion change occurs,android restarts the running Activity ( onDestroy()
is called, followed by onCreate()
).
If you want to handle inside activity,you cant use: in manifest file for particular activity.
For API 12 and below:
android:configChanges="orientation"
if you are targeting API 13 or above
android:configChanges="orientation|screenSize"
Update:Saving Fragment State on Orientation Change
If you want to use onSaveInstanceState
inside activity to save fragment state,You can use putFragment
.
In your activity’s onSaveInstanceState
looks like this:
@Override
protected void onSaveInstanceState(Bundle outState) {
getFragmentManager().putFragment(outState, MyFragment.TAG, mMyFragment);
}
For getting fragment state after activity restart,you can use getFragment
method.
@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();
}
}
Upvotes: 1