Android使用listview实现分页刷新(线程休眠模拟)
程序员文章站
2024-02-27 15:18:57
当要显示的数据过多时,为了更好的提升用户感知,在很多app中都会使用分页刷新显示,比如浏览新闻,向下滑动到当前listview的最后一条信息(item)时,会提示刷新加载,...
当要显示的数据过多时,为了更好的提升用户感知,在很多app中都会使用分页刷新显示,比如浏览新闻,向下滑动到当前listview的最后一条信息(item)时,会提示刷新加载,然后加载更新后的内容。此过程大致分以下几步:
1.当前activity implements onscalllistenner;
2.实现接口的方法;
3.listview注册滚动监听;
4. adapter(自定义或者安卓自带)为每个item填充数据;
5.获得第二页以后的数据后,adater增加数据并刷新notifydatesetchanged();(需要用到handler)
现在我们就通过线程休眠的的方式模拟listview页面刷新的实现(每次加载10条信息,向下滑动会分页刷新加载)
显示效果(设置显示十条后开启刷新,添加使用alertdialog浏览示例):
layout中listview布局activity_main.xml文件:
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.administrator.day08.mainactivity"> <listview android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignparenttop="true" android:layout_alignparentstart="true" /> </relativelayout>
layout中item(填充listview每行)布局item.xml文件:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <textview android:text="tile" android:textsize="30dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/textview" /> <textview android:text="message" android:textsize="20dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/textview2" /> </linearlayout>
layout中页面刷新提示布局(页脚)login_item.xml文件:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <progressbar style="?android:attr/progressbarstyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/progressbar" /> <textview android:text="玩命加载中" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textview3" /> </linearlayout>
java中自定义对象类(每条新闻有对应的标题以及内容)
public class news { string title; string message; }
java中功能实现类(通过实现onscrolllistener接口)
import android.content.dialoginterface; import android.os.handler; import android.os.message; import android.support.v7.app.alertdialog; import android.support.v7.app.appcompatactivity; import android.os.bundle; import android.view.view; import android.view.viewgroup; import android.widget.abslistview; import android.widget.adapterview; import android.widget.baseadapter; import android.widget.listview; import android.widget.textview; import java.util.arraylist; import java.util.list; /** * created by panchengjia on 2016/11/29. */ public class mainactivity extends appcompatactivity implements abslistview.onscrolllistener{ private listview lv; private list<news> news;//声明存储新闻标题与内容的list private int total=1;//计数器(设置默认从1开始)用于集合内数据初始化 myadapter adapter; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); lv= (listview) findviewbyid(r.id.lv); //为当前listview设置onscrolllistener实现分页刷新 lv.setonscrolllistener(this); //将login_item(下拉刷新效果的item)通过布局 填充器声明 view v = getlayoutinflater().inflate(r.layout.login_item,null); //将login_item设置到listview页脚 lv.addfooterview(v); //实例化存储内容资源的list news = new arraylist<>(); //调用初始化list的方法 initlist(); adapter = new myadapter(); //设置单击item的事件 lv.setonitemclicklistener(new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> parent, view view, int position, long id) { show(view);//事件处理为调用show方法(显示alertdialog对话框) } }); lv.setadapter(adapter); } //alertdialog对话框的调用这里就不多说了,前期有专门的博文解释 public void show(view v){ alertdialog.builder builder = new alertdialog.builder(this); textview title = (textview) v.findviewbyid(r.id.textview); textview message = (textview) v.findviewbyid(r.id.textview2); builder.settitle(title.gettext().tostring()); builder.setmessage(message.gettext().tostring()); builder.setpositivebutton("已经浏览完毕", new dialoginterface.onclicklistener() { @override public void onclick(dialoginterface dialog, int which) { } }); builder.show(); } //初始化list内的元素,模拟每次可刷新10条信息 private void initlist() { for(int i=1;i<=10;i++){ news n = new news(); //加total是因为total在刷新页面后不会继续从一开始 n.title = "title--"+total; n.message="message"+total; news.add(n); total++; } } // int currenvisibleitemcount;//声明截止当前页面看到的item总数(演示用) boolean islastrow=false;//判断是否到listview的最后一个item @override public void onscroll(abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) { //firstvisibleitem位可见页面的第一条在arraylist中的下标,visibleitemcount为当前页面item数 // currenvisibleitemcount = firstvisibleitem+visibleitemcount-1=totalitemcount;(演示用) if(firstvisibleitem+visibleitemcount==totalitemcount&&totalitemcount>0){ islastrow=true;//判断已经到最后一个item(即为footerview) } } @override public void onscrollstatechanged(abslistview view, int scrollstate) { /*判断是否刷新页面之前,解释一下scrollstate的三种状态 * 1.scrollstate = scroll_state_touch_scroll为手指按住屏幕滚动(未脱离屏幕); * 2.scrollstate = scroll_state_fling可以理解为手指离开屏幕前,用力滑了一下, * 手指离开后,页面已然保持滚动; * 3.scrollstate = scroll_state_idle手指未接触屏幕,且屏幕页面保持静止 * 开启刷新页面的线程前,确保listview已经到最后一行(item)并且屏幕页面保持静止 * */ if(islastrow&&scrollstate==scroll_state_idle){ new thread(new mythread()).start(); } } //创建分页刷新线程(模拟刷新) class mythread implements runnable{ @override public void run() { try { thread.sleep(500);//设置线程休眠时间为500毫秒刷新一次 } catch (interruptedexception e) { e.printstacktrace(); } initlist();//重新初始化list //线程内调用handler执行页面刷新(后面会写文对handler进行详细剖析) handler.sendemptymessage(1); } } handler handler = new handler(){ @override public void handlemessage(message msg) { super.handlemessage(msg); switch (msg.what){ case 1: //强制调用适配器的getview来刷新每个item的内容。 adapter.notifydatasetchanged(); break; } } }; //自定义适配器 class myadapter extends baseadapter{ @override public int getcount() { return news.size(); } @override public object getitem(int position) { return news.get(position); } @override public long getitemid(int position) { return position; } @override public view getview(int position, view convertview, viewgroup parent) { viewholder vh; if(convertview==null){ convertview = getlayoutinflater().inflate(r.layout.item,null); vh=new viewholder(); vh.message = (textview) convertview.findviewbyid(r.id.textview2); vh.title= (textview) convertview.findviewbyid(r.id.textview); convertview.settag(vh); } vh= (viewholder) convertview.gettag(); vh.title.settext(news.get(position).title); vh.message.settext(news.get(position).message); return convertview; } class viewholder{ textview title; textview message; } } }
至此listview的分页刷新源码已全部展示完成,个人认为实现此功能的核心为判断是否达到当前listview中的最后一条item(包含页脚刷新提示)以及理解scrollstate的状态,理解了这两点,该功能的实现起来事半功倍。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。