无法使用无限滚动加载数据

时间:2015-01-21 17:26:35

标签: android json android-fragments endlessscroll

我是Android的新手,一时间陷入困境。 我在一家公司工作,但我没有人给你建议。我的应用程序就像RSS提要。我必须从API加载数据,它返回我的JSON对象。 API的地址是http://itvdn-api.azurewebsites.net/api/news/1。现在只有4页。我正在立即从第一页加载信息,然后当剩下2个项目时,我正在尝试加载下一个。它加载第二页但随后停止加载。我尝试调试,在它解析第3页后,我被扔到了AbsListView.java。应用程序运行正常,没有任何崩溃。

这是Fragment类,我代表解析数据。

public class NewsFragment extends android.support.v4.app.Fragment implements AbsListView.OnItemClickListener {

private static final String ARG_SECTION_NUMBER = "section_number";

private ArrayList<NewsBlogData> newsData;


private OnFragmentInteractionListener mListener;

/**
 * The fragment's ListView/GridView.
 */
private AbsListView mListView;

/**
 * The Adapter which will be used to populate the ListView/GridView with
 * Views.
 */
private NewsBlogItemAdapter mAdapter;

// TODO: Rename and change types of parameters
public static NewsFragment newInstance(int sectionNumber) {
    NewsFragment fragment = new NewsFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    fragment.setArguments(args);
    return fragment;
}

/**
 * Mandatory empty constructor for the fragment manager to instantiate the
 * fragment (e.g. upon screen orientation changes).
 */
public NewsFragment() {
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    // TODO: Change Adapter to display your content
    /*mAdapter = new ArrayAdapter<DummyContent.DummyItem>(getActivity(),
            android.R.layout.simple_list_item_1, android.R.id.text1, DummyContent.News);*/
    newsData = new ParserJson().getNewsBlogData(1);
    mAdapter = new NewsBlogItemAdapter(getActivity(),
            R.layout.news_blog_list_item,
            newsData);

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_news, container, false);

    // Set the adapter
    mListView = (AbsListView) view.findViewById(android.R.id.list);
    mListView.setAdapter(mAdapter);

    // Set OnItemClickListener so we can be notified on item clicks
    mListView.setOnItemClickListener(this);
    //mListView.setOnScrollListener(new EndlessScrollListener());
    mListView.setOnScrollListener(new EndlessScrollListener() {

        @Override
        public void onLoadMore(int page, int totalItemsCount) {
            // TODO Auto-generated method stub
            newsData.addAll(new ParserJson().getNewsBlogData(page));

        }
    });

    return view;
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentInteractionListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnFragmentInteractionListener");
    }
    ((NavigationActivity) activity).onSectionAttached(
            getArguments().getInt(ARG_SECTION_NUMBER));
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}


@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    //FragmentManager fragmentManager = NavigationActivity.getSupportFragmentManager();
}

/**
 * The default content for this Fragment has a TextView that is shown when
 * the list is empty. If you would like to change the text, call this method
 * to supply the text it should use.
 */
public void setEmptyText(CharSequence emptyText) {
    View emptyView = mListView.getEmptyView();

    if (emptyView instanceof TextView) {
        ((TextView) emptyView).setText(emptyText);
    }
}

/**
 * This interface must be implemented by activities that contain this
 * fragment to allow an interaction in this fragment to be communicated
 * to the activity and potentially other fragments contained in that
 * activity.
 * <p/>
 * See the Android Training lesson <a href=
 * "http://developer.android.com/training/basics/fragments/communicating.html"
 * >Communicating with Other Fragments</a> for more information.
 */
public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    public void onNewsFragmentInteraction(String id);
}

}

这是我在endless scroll list view上找到的EndlessScrollListener

public abstract class EndlessScrollListener implements AbsListView.OnScrollListener {
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 2;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private int startingPageIndex = 1;

public EndlessScrollListener() {
}

public EndlessScrollListener(int visibleThreshold) {
    this.visibleThreshold = visibleThreshold;
}

public EndlessScrollListener(int visibleThreshold, int startPage) {
    this.visibleThreshold = visibleThreshold;
    this.startingPageIndex = startPage;
    this.currentPage = startPage;
}

// This happens many times a second during a scroll, so be wary of the code
// you place here.
// We are given a few useful parameters to help us work out if we need to
// load some more data,
// but first we check if we are waiting for the previous load to finish.
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
                     int visibleItemCount, int totalItemCount) {
    // If the total item count is zero and the previous isn't, assume the
    // list is invalidated and should be reset back to initial state
    // If there are no items in the list, assume that initial items are
    // loading
    if (!loading && (totalItemCount < previousTotalItemCount)) {
        this.currentPage = this.startingPageIndex;
        this.previousTotalItemCount = totalItemCount;
        if (totalItemCount == 0) {
            this.loading = true;
        }
    }

    // If it’s still loading, we check to see if the dataset count has
    // changed, if so we conclude it has finished loading and update the
    // current page
    // number and total item count.
    if (loading) {
        if (totalItemCount > previousTotalItemCount) {
            loading = false;
            previousTotalItemCount = totalItemCount;
            currentPage++;
        }
    }

    // If it isn’t currently loading, we check to see if we have breached
    // the visibleThreshold and need to reload more data.
    // If we do need to reload some more data, we execute onLoadMore to
    // fetch the data.
    if (!loading
            && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
        onLoadMore(currentPage + 1, totalItemCount);
        loading = true;
    }
}

// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    // Don't take any action on changed
}
}

请告诉我是否可以通过其他方式完成所有事情,或者可能是我应该附加其他代码或日志数据。

1 个答案:

答案 0 :(得分:1)

我在stackoverflow上找到了答案。现在我的片段实现了OnScrollListener,而不是单独创建类。

我的代码看起来像这样

public class NewsFragment extends android.support.v4.app.Fragment implements
             AbsListView.OnItemClickListener, AbsListView.OnScrollListener {

private static final String ARG_SECTION_NUMBER = "section_number";
// Amount of items in the end of the list that should trigger the loading
private int threshold = 2;
// The index of the page from where I'm loading data
private int currentPage = 1;

// The list that is represented in the ListView
private ArrayList<NewsBlogData> newsData;

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
                     int visibleItemCount, int totalItemCount) {
    //leave this empty
}

@Override
public void onScrollStateChanged(AbsListView listView, int scrollState) {
    if (scrollState == SCROLL_STATE_IDLE) {
        if (listView.getLastVisiblePosition() >= listView.getCount() - 1 - threshold) {
            currentPage++;
            //load more list items:
            newsData.addAll(new ParserJson().getNewsBlogData(currentPage));
            mAdapter.notifyDataSetChanged();
        }
    }
}

Android Endless List

找到了这个答案

仅添加

mAdapter.notifyDataSetChanged();

因为数据不是从主线程加载的。

可能它应该与EndlessScrollListener一起作为一个单独的类使用,但我没有测试它。