我是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
}
}
请告诉我是否可以通过其他方式完成所有事情,或者可能是我应该附加其他代码或日志数据。
答案 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();
}
}
}
找到了这个答案
仅添加
mAdapter.notifyDataSetChanged();
因为数据不是从主线程加载的。
可能它应该与EndlessScrollListener一起作为一个单独的类使用,但我没有测试它。