上拉加载更多

    xiaoxiao2025-04-18  15

    上拉加载更多demo分析+实现:

         

    (效果如图至于乱码,是demo是gbk,用utf-8打开,并无大碍)

    让我们接下来搞一搞这坨吧,然后下一坨搞一搞下拉刷新:

    一. 我们就一个MainActivity来进行的页面:

    首先:一个ListView搞出来:

    <ListView android:id="@+id/ll_main" android:layout_width="wrap_content" android:layout_height="wrap_content" />然后:搞一个listviewitem出来:

    <TextView android:id="@+id/tv_item" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="让我们一起摇摆" android:layout_gravity="center"/>最后:搞一个上拉加载更多的东西:

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="20dip" android:paddingBottom="20dip" android:orientation="horizontal" android:visibility="gone" > <ProgressBar android:id="@+id/progressBar2" style="?android:attr/progressBarStyleSmall" android:layout_gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/loadmore_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="18dip" android:text="数据加载中..." /> </LinearLayout> 

    二. 接下来就是一些代码实现了:

    package com.xzw.demo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.View; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; import java.util.ArrayList; import java.util.HashMap; public class MainActivity extends Activity implements OnScrollListener { private static final String TAG = "MainActivity"; private ListView listView; private View moreView; //加载更多页面 private SimpleAdapter adapter; private ArrayList<HashMap<String, String>> listData; private int lastItem; private int count; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView)findViewById(R.id.listView); moreView = getLayoutInflater().inflate(R.layout.load, null); listData = new ArrayList<HashMap<String,String>>(); prepareData(); //准备数据 count = listData.size(); adapter = new SimpleAdapter(this, listData,R.layout.item, new String[]{"itemText"}, new int[]{R.id.itemText}); listView.addFooterView(moreView); //添加底部view,一定要在setAdapter之前添加,否则会报错。 listView.setAdapter(adapter); //设置adapter listView.setOnScrollListener(this); //设置listview的滚动事件 } private void prepareData(){ //准备数据 for(int i=0;i<10;i++){ HashMap<String, String> map = new HashMap<String, String>(); map.put("itemText", "测试数据"+i); listData.add(map); } } private void loadMoreData(){ //加载更多数据 count = adapter.getCount(); for(int i=count;i<count+5;i++){ HashMap<String, String> map = new HashMap<String, String>(); map.put("itemText", "测试数据"+i); listData.add(map); } count = listData.size(); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { Log.i(TAG, "firstVisibleItem="+firstVisibleItem+"\nvisibleItemCount="+ visibleItemCount+"\ntotalItemCount"+totalItemCount); lastItem = firstVisibleItem + visibleItemCount - 1; //减1是因为上面加了个addFooterView } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { Log.i(TAG, "scrollState="+scrollState); //下拉到空闲是,且最后一个item的数等于数据的总数时,进行更新 if(lastItem == count && scrollState == this.SCROLL_STATE_IDLE){ Log.i(TAG, "拉到最底部"); moreView.setVisibility(view.VISIBLE); mHandler.sendEmptyMessage(0); } } //声明Handler private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg) { switch (msg.what) { case 0: try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } loadMoreData(); //加载更多数据,这里可以使用异步加载 adapter.notifyDataSetChanged(); moreView.setVisibility(View.GONE); if(count > 30){ Toast.makeText(MainActivity.this, "木有更多数据!", Toast.LENGTH_LONG).show(); listView.removeFooterView(moreView); //移除底部视图 } Log.i(TAG, "加载更多数据"); break; case 1: break; default: break; } }; }; } 主要分为这么几个部分:

    数据准备:是将我们用到的数据放到一个hashmap的arraylist中,通过循环将数据加入:

    for(int i=0;i<10;i++){ HashMap<String, String> map = new HashMap<String, String>(); map.put("itemText", "测试数据"+i); listData.add(map); }(初始0-9,共十条数据,测试数据0-9)

    数据更多:是创造更多的数据到arraylist中,依旧是循环添加:

    count = adapter.getCount(); for(int i=count;i<count+5;i++){ HashMap<String, String> map = new HashMap<String, String>(); map.put("itemText", "测试数据"+i); listData.add(map); } count = listData.size();继续添加呗;注意count的变化即可。每次数据改变之后,修改count,使moredata能够正确加载更多数据

    onScroll和onScrollStateChanged是implements AbsListView.OnScrollListener之后的方法,主要是用来监听滑动事件:

    onScroll:

    lastItem = firstVisibleItem + visibleItemCount - 1; //减1是因为上面加了个addFooterView onScrollStateChanged:

    if(lastItem == count && scrollState == this.SCROLL_STATE_IDLE){ Log.i(TAG, "拉到最底部"); moreView.setVisibility(view.VISIBLE); mHandler.sendEmptyMessage(0); } mHandle:

    private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg) { switch (msg.what) { case 0: try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } loadMoreData(); //加载更多数据,这里可以使用异步加载 adapter.notifyDataSetChanged(); moreView.setVisibility(View.GONE); if(count > 30){ Toast.makeText(MainActivity.this, "木有更多数据!", Toast.LENGTH_LONG).show(); listView.removeFooterView(moreView); //移除底部视图 } Log.i(TAG, "加载更多数据"); break; case 1: break; default: break; } }; }; 总结来说就是:

    不断的去改变item的count,在拖动到item到底-1意味着要把加载更多数据这个不算,然后并且是停止状态且“手指”未在item上,moreView可见,之后我们handler发一个空消息,然后去handmessage中去判断哪个消息,在该方法加载更多数据,刷新adapter,并将moreView不可见。

    在最后我们去了解几个方法:

    (a)SimpleAdapter

    SimpleAdapter是扩展性最好的适配器,可以定义各种你想要的布局。

    第一个参数 表示访问整个android应用程序接口,基本上所有的组件都需要。 第二个参数表示生成一个Map(String ,Object)列表选项 第三个参数表示界面布局的id  表示该文件作为列表项的组件 第四个参数表示该Map对象的哪些key对应value来生成列表项 第五个参数表示来填充的组件 Map对象key对应的资源一依次填充组件 顺序有对应关系 注意的是map对象可以key可以找不到 但组件的必须要有资源填充  因为 找不到key也会返回null 其实就相当于给了一个null资源

    adapter=new SimpleAdapter(this,listData,R.layout.listview_main_item, new String[]{"itemText"},new int[]{R.id.tv_item});在本例子中,依次:

    上下文

    数据

    item布局

    数据中的对应,比如我们的数据是hanshmap--->键值对是ietmText,测试数据+i--->此处对应的键

    此处对应键值对中对应的哪一个id也就是哪一个控件,这样就将某控件与数据联系起来,且把item布局联系起来

    (b)onScroll

    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) /** * firstVisibleItem 表示在当前屏幕<span style="color:#FF0000;">显示</span>的第一个listItem在整个listView里面的位置(下标从0开始) * visibleItemCount表示在现时屏幕<span style="color:#FF0000;">可以见到</span>的ListItem(部分显示的ListItem也算)<span style="color:#FF0000;">总数</span> * totalItemCount表示<span style="color:#FF0000;">ListView的ListItem总数</span> * listView.<span style="color:#FF0000;">getLast</span>VisiblePosition()表示在现时屏幕最后一个ListItem * (最后ListItem要完全显示出来才算)在整个ListView的位置(下标从0开始) */ 此处主要用来判断到没到底部 此处主要用来得到底部

    (c)onScrollStateChanged 滑动状态

    在此处判断静止,并且加上判断是否到底部来进行下一步操作

    ——————————————————————————————

       

    ——————

    在代码中Progressbar 是引入了新的style,但是自己并没有去引入,所以与demo有出入

    转载请注明原文地址: https://ju.6miu.com/read-1298182.html
    最新回复(0)