I tried to use viewpager and listview fragment in it with volley request.
When I first run program, I can see logs that I recieved data from api for both 1st and 2nd page. In that case 1st page shows blank page.
When I swipe to 2nd page I can see page with correct data if volley request came. In the same time I recieved 3rd page data from api(Because viewpager crates an instance of 3rd page). But when I click on item in 2nd page I get "The content of the adapter has changed but ListView did not receive a notification."
If I don't click on item in 2nd page and swipe to 3rd, I can see 3rd page with correct data and when I click on item it shows correct activity.
Invoking notifyDataSetChanged();
when I get response from api and tried setOffscreenPageLimit(0);
to reload every page but nothing changes.
Here is my Adapters, Fragment and ServiceHandler classes.
MovieListAdapter
public class MovieListAdapter extends BaseAdapter {
private LayoutInflater l_Inflater;
private static List<MovieDetailModel> itemDetailsList;
private RequestQueue queue;
private ViewHolder holder;
//Constructor
public MovieListAdapter(Context context, List<MovieDetailModel> results) {
itemDetailsList = results;
l_Inflater = LayoutInflater.from(context);
queue = VolleySingleton.getInstance().getRequestQueue();
}
@Override
public int getCount() {
return itemDetailsList.size();
}
@Override
public Object getItem(int i) {
return itemDetailsList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
//Holder pattern -> If new view required, create item for list
if (view == null) {
view = l_Inflater.inflate(R.layout.item_movie, null);
initializeHolder(view);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
setHolderItems(itemDetailsList, position);
return view;
}
static class ViewHolder {
TextView txt_title;
TextView txt_synopsis;
NetworkImageView itemImage;
}
private void initializeHolder(View view) {
holder = new ViewHolder();
holder.txt_title = (TextView) view.findViewById(R.id.title);
holder.txt_synopsis = (TextView) view.findViewById(R.id.synopsis);
holder.itemImage = (NetworkImageView) view.findViewById(R.id.list_image);
}
private void setHolderItems(List<MovieDetailModel> movieDetailModels, int position) {
holder.txt_title.setText(movieDetailModels.get(position).getTitle());
holder.txt_synopsis.setText(movieDetailModels.get(position).getSynopsis());
holder.itemImage.setImageUrl(movieDetailModels.get(position).getPosters().getThumbnail(), VolleySingleton.getInstance().getImageLoader());
}
}
TabsPagerAdapter
public class TabsPagerAdapter extends FragmentStatePagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
return MovieListFragment.newInstance(index);
}
@Override
public int getCount() {
// get item count - equal to number of tabs
return Constants.TAB_COUNT;
}
}
MovieListFragment
public class MovieListFragment extends Fragment {
List<MovieDetailModel> movieDetailModelList;
public static MovieListAdapter movieListAdapter;
private int viewPagerPage;
OnMovieSelected movieItemClickListener;
public static MovieListFragment newInstance(int tabNumver){
MovieListFragment fragment = new MovieListFragment();
Bundle args = new Bundle();
args.putInt(Constants.ARG_TAB_ID,tabNumver);
fragment.setArguments(args);
return fragment;
}
public MovieListFragment(){
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
movieItemClickListener = (OnMovieSelected) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onMovieSelected");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
viewPagerPage = getArguments().getInt(Constants.ARG_TAB_ID);
if (Constants.LOGS_ACTIVE) {
Log.d("TAB_ID", viewPagerPage + "");
}
View rootView = inflater.inflate(R.layout.fragment_movie_list, container, false);
ListView moviesListView = (ListView) rootView.findViewById(R.id.listview_movie_list);
setListView(moviesListView);
return rootView;
}
public List<MovieDetailModel> getSelectedMovieList(int tabId) {
switch (tabId) {
case 0:
return ServiceHandler.makeStringVolleyReq(Constants.BOX_OFFICE_LINK, getActivity());
case 1:
return ServiceHandler.makeStringVolleyReq(Constants.TOP_RENTALS_LINK, getActivity());
case 2:
return ServiceHandler.makeStringVolleyReq(Constants.UPCOMING_LINK, getActivity());
default:
return null;
}
}
private void setListView(ListView listView) {
movieDetailModelList = getSelectedMovieList(viewPagerPage);
movieListAdapter = new MovieListAdapter(getActivity(), movieDetailModelList);
listView.setAdapter(movieListAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
movieItemClickListener.onMovieSelected(movieDetailModelList.get(i));
Intent intent = new Intent(getActivity(), ActMovieDetails.class);
intent.putExtra(Constants.TAG_MOVIE, movieDetailModelList.get(i));
startActivity(intent);
} else {
if (Constants.LOGS_ACTIVE) {
Log.d("ORIETNTATION", "LANDSCAPE BUTTON");
}
movieItemClickListener.onMovieSelected(movieDetailModelList.get(i));
}
}
});
}
//For Callbacks
public interface OnMovieSelected {
public void onMovieSelected(MovieDetailModel movieDetailModel);
}
}
ServiceHandler
public static List<MovieDetailModel> makeStringVolleyReq(String url, final Context context) {
RequestQueue queue = VolleySingleton.getInstance().getRequestQueue();
ImageLoader mImageLoader;
final List<MovieDetailModel> movieList = new ArrayList<MovieDetailModel>();
StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// we got the response, now our job is to handle it
if(Constants.LOGS_ACTIVE) {
Log.d("JSON STRING: ", response);
}
movieList.addAll(JSONHandler.convertJSONArrayString2MoviesDetailModels(response));
if(Constants.LOGS_ACTIVE) {
for (int i = 0; i < movieList.size(); i++) {
Log.d("MOVIE", movieList.get(i).getTitle());
}
}
//ASK: How to set non-static?
MovieListFragment.movieListAdapter.notifyDataSetChanged();
if(SearchResultsActivity.searchResultsMovieListAdapter!=null){
SearchResultsActivity.searchResultsMovieListAdapter.notifyDataSetChanged();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//something happened, treat the error.
}
});
queue.add(stringRequest);
return movieList;
}