这是我第一次使用onscroll监听器.我的问题是每次向下滚动时如何获取20个新行?
我理解当我向下滚动网格视图时,将执行此代码.
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
this.currentFirstVisibleItem = firstVisibleItem;
this.currentVisibleItemCount = visibleItemCount;
this.totalItem = totalItemCount;
if ((totalItemCount - visibleItemCount) <= (firstVisibleItem + 20)) {
// the below when executed will get all the rows ,I only need 20 rows
handler.execute().get();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的代码
// the load more in the grid view, fetch new images.
mGridView.setOnScrollListener(new AbsListView.OnScrollListener() {
private int currentVisibleItemCount;
private int currentScrollState;
private int currentFirstVisibleItem;
private int totalItem;
private LinearLayout lBelow;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
this.currentScrollState = scrollState;
this.isScrollCompleted();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
this.currentFirstVisibleItem = firstVisibleItem;
this.currentVisibleItemCount = visibleItemCount;
this.totalItem = totalItemCount;
if ((totalItemCount - visibleItemCount) <= (firstVisibleItem + 20)) {
// load new 20 row but how to do that
}
}
private void isScrollCompleted() {
if (totalItem - currentFirstVisibleItem == currentVisibleItemCount
&& this.currentScrollState == SCROLL_STATE_IDLE) {
Log.d("a", "poooppii");
}
}
;
});
Run Code Online (Sandbox Code Playgroud)
这是连接发生的地方
protected void showList(){
try {
JSONObject jsonObj = new JSONObject(myJSON);
peoples = jsonObj.getJSONArray("result");
System.out.println("Length:"+peoples.length());
int J_length=peoples.length()-1;
jsonObj= peoples.getJSONObject(J_length);
Listitem = new ArrayList<Listitem>();
for (int i = 0; i < peoples.length(); i++) {
JSONObject c = peoples.getJSONObject(i);
String id = c.getString("id");
String url = c.getString("url");
int intid = 0;
try {
intid = Integer.parseInt(id.toString());
} catch (NumberFormatException nfe) {
System.out.println("Could not parse " + nfe);
}
Listitem.add(new Listitem(id, url));
System.out.println(Listitem);
}
//}
if (mListener != null)
mListener.myMethod(Listitem);
} catch (JSONException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
您需要维护base和limit加载数据.初始化您的基数和限制变量.
int base = 0, limit = 20;
Run Code Online (Sandbox Code Playgroud)
base加载新项目时增加变量.
base = base + limit;
handler.execute().get();
Run Code Online (Sandbox Code Playgroud)
在通话中传递base和limit变量API,以便您可以在API旁边查询中使用它.
注意:base是一个值,您需要从该位置开始获取值.limit是您需要获取的行数的值.
请参阅本在sqlite的限制查询.
请参阅此提供在MySQL限制查询.
请参阅本在SQL查询的限制.
这是一个工作代码,请根据您的使用进行修改 -
假设以下是您的模型 -
public class MyModel {
String name;
}
Run Code Online (Sandbox Code Playgroud)
您需要一个界面 -
public interface PagingListener<T> {
void onItemUpdate(ArrayList<T> allData);
}
Run Code Online (Sandbox Code Playgroud)
像这样设计你的适配器 -
public class CouponsAdapter extends RecyclerView.Adapter<CouponsAdapter.CouponHolder> implements View.OnClickListener, PagingListener<MyModel> {
private final static int TYPE_LOADING = 0;
private final static int TYPE_DATA = 1;
private FragmentActivity activity;
private LayoutInflater inflater;
private PagingRequestHandler<MyModel> pagingRequestHandler;
private ArrayList<MyModel> data = null;
public CouponsAdapter(FragmentActivity activity) {
this.activity = activity;
inflater = LayoutInflater.from(activity);
this.data = new ArrayList<>();
this.pagingRequestHandler = new PagingRequestHandler<>(data, this);
}
@Override
public int getItemViewType(int position) {
return position >= data.size() ? TYPE_LOADING : TYPE_DATA;
}
@Override
public CouponHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == TYPE_DATA) {
view = inflater.inflate(R.layout.item_coupons_card_block, parent, false);
} else {
view = inflater.inflate(R.layout.item_drawer_payment_loading, parent, false);
}
return new CouponHolder(view, viewType);
}
@Override
public void onBindViewHolder(CouponHolder holder, int position) {
if (getItemViewType(position) == TYPE_DATA) {
//Bind your view here
}
pagingRequestHandler.checkAndMakeRequestForMoreData(position); //Will check and make request
}
@Override
public int getItemCount() {
return data.size() + (pagingRequestHandler.isNoMoreDataLeft() ? 0 : 1); // If no data then it will return 1 to show loading
}
@Override
public void onClick(View v) {
}
@Override
public void onItemUpdate(ArrayList<MyModel> allData) {
this.data = allData; // will update data with updated content
notifyDataSetChanged();
}
public class CouponHolder extends RecyclerView.ViewHolder {
public CouponHolder(View itemView, int itemType) {
super(itemView);
if (itemType == TYPE_DATA) {
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在这是分页请求处理程序,它将跟踪页码并发出下一页的请求 -
public class PagingRequestHandler<T> {
public static final int PAGE_SIZE = 10;
private final PagingListener listener;
private final ArrayList<MyModel> arrayList;
private final String url = "Your Url here";
private boolean noMoreDataLeft;
private int pagingIndex = 0;
private boolean requestGoingOn;
public PagingRequestHandler(ArrayList<MyModel> data, PagingListener<MyModel> listener) {
this.listener = listener;
this.arrayList = data;
fetchMoreData();
}
private void fetchMoreData() {
requestGoingOn = true;
Call<MyModel[]> getCoupons = Utils.getRetrofit().getCoupons(url + "/" + pagingIndex); // I am using retrofit for network call, you can use your own
getCoupons.enqueue(new Callback<MyModel[]>() {
@Override
public void onResponse(Response<MyModel[]> response, Retrofit retrofit) {
try {
requestGoingOn = false;
MyModel[] couponModelDses = response.body();
if (couponModelDses != null) {
for (MyModel couponModelDse : couponModelDses) {
arrayList.add(couponModelDse);
}
if (couponModelDses.length < PAGE_SIZE)
noMoreDataLeft = true;
listener.onItemUpdate(arrayList);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable t) {
requestGoingOn = false;
}
});
}
public boolean isNoMoreDataLeft() {
return noMoreDataLeft;
}
public void checkAndMakeRequestForMoreData(int position) {
if (!noMoreDataLeft && !requestGoingOn && position > (PAGE_SIZE * pagingIndex)) {
if ((position % PAGE_SIZE) > (int) (PAGE_SIZE * .7)) {
pagingIndex++;
fetchMoreData();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
工作原理 -适配器正在初始化处理程序,这是第一次进行网络调用。适配器现在调用处理程序 api 来检查每次 onBind 时是否滚动了 70% 的页面。现在,如果已显示 70% 的数据,则它会再次进行网络调用并使名为 requestGoingOn 的变量为 true,以便您可以在列表中显示加载程序。当请求完成时,处理程序将数据添加到 arraylist 并通过调用回调更新适配器onItemUpdate。
希望它会有所帮助,如果您需要进一步的帮助,请告诉我:)
| 归档时间: |
|
| 查看次数: |
218 次 |
| 最近记录: |