让我简要解释一下我的活动结构。当用户输入应用程序时,它们会立即发送到显示ScrollView的片段,其中包含一系列布局。布局由从服务器提取的数据填充,前十个左右加载了片段的创建。当用户向下滚动ScrollView时,我希望将新布局添加到ScrollView的底部,这样就不必立即从服务器收集所有数据,因此条目列表不会超过它需要的大小。
这方面的一个例子是Facebook的Android应用程序的新闻源,或Instagram的滚动图片。 Gmail应用也会出现此行为,并根据需要加载电子邮件。在所有情况下,当用户向下滚动页面时,将加载新数据。
我的问题是,这种行为的实施效果如何?
我最好定义为:
要明确,我不仅仅是在寻找 解决方案,而是最好的解决方案。我知道有多种方法可以实现这种行为,但我正在寻找一个明确的解决方案。请提供几句话来解释为什么您的方法是最好的。谢谢。
答案 0 :(得分:0)
您可以使用此类从服务器加载更多项目
公共类LoadMoreListView扩展了ListView实现的OnScrollListener {
private static final String TAG = "LoadMoreListView";
/**
* Listener that will receive notifications every time the list scrolls.
*/
private OnScrollListener mOnScrollListener;
private LayoutInflater mInflater;
// footer view
private RelativeLayout mFooterView;
// private TextView mLabLoadMore;
private ProgressBar mProgressBarLoadMore;
// Listener to process load more items when user reaches the end of the list
private OnLoadMoreListener mOnLoadMoreListener;
// To know if the list is loading more items
private boolean mIsLoadingMore = false;
private int mCurrentScrollState;
public LoadMoreListView(Context context) {
super(context);
init(context);
}
public LoadMoreListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public LoadMoreListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// footer
mFooterView = (RelativeLayout) mInflater.inflate(
R.layout.load_more_footer, this, false);
/*
* mLabLoadMore = (TextView) mFooterView
* .findViewById(R.id.load_more_lab_view);
*/
mProgressBarLoadMore = (ProgressBar) mFooterView
.findViewById(R.id.load_more_progressBar);
addFooterView(mFooterView);
super.setOnScrollListener(this);
}
@Override
public void setAdapter(ListAdapter adapter) {
super.setAdapter(adapter);
}
/**
* Set the listener that will receive notifications every time the list
* scrolls.
*
* @param l
* The scroll listener.
*/
@Override
public void setOnScrollListener(AbsListView.OnScrollListener l) {
mOnScrollListener = l;
}
/**
* Register a callback to be invoked when this list reaches the end (last
* item be visible)
*
* @param onLoadMoreListener
* The callback to run.
*/
public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
mOnLoadMoreListener = onLoadMoreListener;
}
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (mOnScrollListener != null) {
mOnScrollListener.onScroll(view, firstVisibleItem,
visibleItemCount, totalItemCount);
}
if (mOnLoadMoreListener != null) {
if (visibleItemCount == totalItemCount) {
mProgressBarLoadMore.setVisibility(View.GONE);
// mLabLoadMore.setVisibility(View.GONE);
return;
}
boolean loadMore = firstVisibleItem + visibleItemCount >= totalItemCount;
if (!mIsLoadingMore && loadMore
&& mCurrentScrollState != SCROLL_STATE_IDLE) {
mProgressBarLoadMore.setVisibility(View.VISIBLE);
// mLabLoadMore.setVisibility(View.VISIBLE);
mIsLoadingMore = true;
onLoadMore();
}
}
}
public void onScrollStateChanged(AbsListView view, int scrollState) {
// bug fix: listview was not clickable after scroll
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
view.invalidateViews();
}
mCurrentScrollState = scrollState;
if (mOnScrollListener != null) {
mOnScrollListener.onScrollStateChanged(view, scrollState);
}
}
public void onLoadMore() {
Log.d(TAG, "onLoadMore");
if (mOnLoadMoreListener != null) {
mOnLoadMoreListener.onLoadMore();
}
}
/**
* Notify the loading more operation has finished
*/
public void onLoadMoreComplete() {
mIsLoadingMore = false;
mProgressBarLoadMore.setVisibility(View.GONE);
}
/**
* Interface definition for a callback to be invoked when list reaches the
* last item (the user load more items in the list)
*/
public interface OnLoadMoreListener {
/**
* Called when the list reaches the last item (the last item is visible
* to the user)
*/
public void onLoadMore();
}
}
这是用于从server加载更多项的自定义List视图。你应该使用LoadMoreListView类来完成这项工作。你可以像这样在xml中调用这个类
<com.broadpeak.nvoice.utils.LoadMoreListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
lmlv = (LoadMoreListView) view.findViewById(R.id.lv);
lmlv.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
}
});
如果有任何查询,那么您可以自由联系....
答案 1 :(得分:0)
您尝试使用的方法称为 LazyLoading
作为Android开发中的建议方式,您可以使用recycler views
和RecyclerAdapter
来实现此目的。
首先定义Recycler适配器和视图
然后,您可以将onScrollListener
设置为回收适配器,它应该像(Original Source)
public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();
private int previousTotal = 0; // The total number of items in the dataset after the last load
private boolean loading = true; // True if we are still waiting for the last set of data to load.
private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more.
int firstVisibleItem, visibleItemCount, totalItemCount;
private int current_page = 1;
private LinearLayoutManager mLinearLayoutManager;
public EndlessRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) {
this.mLinearLayoutManager = linearLayoutManager;
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mLinearLayoutManager.getItemCount();
firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
// like Load from server
current_page++;
onLoadMore(current_page);
loading = true;
}
}
public abstract void onLoadMore(int current_page);
}
正如您所看到的那样,您可以使用onScrolled
方法发出服务器请求,我认为您可以使用 RetroFit 或 okHttp