Listview获取"适配器的内容已更改,但ListView未收到通知。"

时间:2014-05-10 20:31:37

标签: android listview android-fragments android-viewpager android-volley

我试图在其中使用viewpager和listview片段,同时使用截击请求。

当我第一次运行程序时,我可以在第1页和第2页看到我从api收到数据的日志。在这种情况下,第一页显示空白页。

当我滑动到第二页时,如果有凌空请求,我可以看到包含正确数据的页面。在同一时间,我从api收到第3页数据(因为viewpager创建了第3页的实例)。但是当我点击第二页中的项目时,我得到了#34;适配器的内容已经改变,但ListView没有收到通知。"

如果我没有点击第二页中的项目并滑动到第三页,我可以看到第三页包含正确的数据,当我点击项目时,它显示正确的活动。

当我从api收到回复时调用notifyDataSetChanged();并尝试setOffscreenPageLimit(0);重新加载每个页面但没有任何变化。

这是我的Adapters,Fragment和ServiceHandler类。

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扩展了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;
    }

2 个答案:

答案 0 :(得分:1)

您正尝试从不同的线程更新listView。

您应该在UI线程中调用notifyDataSetChanged()来解决此问题。

Android basics: running code in the UI thread

答案 1 :(得分:0)

我的问题是MovieListAdapter中的静态itemDetailsList。

我没有注意到这一切,并尝试了一切。

感谢您的回复。