【声明】

欢迎转载,但请保留文章原始出处→_→

生命壹号:http://www.cnblogs.com/smyhvae/

文章来源:http://www.cnblogs.com/smyhvae/p/3910541.html

【正文】

一、具体步骤:

(1)在activiy_main.xml中加一个ListView控件;再添加一个item的模板activity_main_item.xml,加一个底部加载的视图activity_main_load.xml;

(2)初始化item中的数据;

(3)自定义适配器BaseAdapter;

(4)ListiView绑定监听器OnScrollListener,并实现该监听器的两个方法:

    • public void onScrollStateChanged(AbsListView view, int scrollState)
    • public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount)

注:如果屏幕滑到最下面了,并且scrollState的状态为:滚动完毕之后ListView处于停止状态(手离开屏幕),此时可以加载新数据了

(5)通过额外的线程,来模拟加载新数据;

(6)新数据加载完成后,通过handle通知主线程,将这个新数据显示在UI界面上(因为涉及到线程安全问题),此时要调用notifyDataSetChanged()方法来刷新。

注:handler为线程之间通信的桥梁

二、代码实现:

完整版代码如下:

activiy_main.xml代码如下:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>

注:为优化起见,第9行的代码一定要写成"match_parent",而不是“wrap_content”(解释略)

activity_main_item.xml代码如下:(作为一个item的模板)

 <?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="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textView2_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>

activity_main_load.xml代码如下:(作为加载时底部的显示)

 <?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:orientation="horizontal"
android:gravity="center" > <ProgressBar
android:id="@+id/progressBar1"
android:layout_width="25dp"
android:layout_height="25dp" /> <TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在加载···" /> </LinearLayout>

MainActivity.java代码如下:

 package com.smyhvae.smyh005listview5;

 import java.util.Vector;

 import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView; public class MainActivity extends Activity { private ListView listView;
Vector<News> news = new Vector<News>();
//private ArrayList<News> news = new ArrayList<News>();上面一行与这一行,二选一
MyAdapter myAdapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listView1); listView.setOnScrollListener(new ListViewListener()); //绑定监听器 //设置底部视图
View footer = getLayoutInflater().inflate(R.layout.activity_main_load, null);
listView.addFooterView(footer); // initData();
new LoadDataThread().start();//加载数据的工作线程 myAdapter = new MyAdapter();
listView.setAdapter(myAdapter);
} //定义一个数据的类
class News {
String title;
String content;
} int index = 1;//数据的记数器(索引)
//初始化数据
void initData(){
System.out.println("initData");
for (int i = 0; i < 15; i++) {
News n = new News(); //这句话一定要放在循环的里面,否则每个item显示的内容都是一样的
n.title = "title-"+index;
n.content = "content"+index;
index++;
news.add(n); //这一步很关键,我就是少了这一步,导致运行时,界面为空
}
} //自定义适配器
class MyAdapter extends BaseAdapter{ @Override
public int getCount() {
// TODO Auto-generated method stub
return news.size();
}
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 viewHolder = new ViewHolder();
//通过下面的条件判断语句,来循环利用。如果convertView = null ,表示屏幕上没有可以被重复利用的对象。
if(convertView==null){
//创建View
convertView = getLayoutInflater().inflate(R.layout.activity_main_item, null);
viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.textView1_title);
viewHolder.tvContent = (TextView) convertView.findViewById(R.id.textView2_content);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder)convertView.getTag();
}
//从Vector中取出数据填充到ListView列表项中
News n = news.get(position);
viewHolder.tvTitle.setText(n.title);
viewHolder.tvContent.setText(n.content);
return convertView;
} } static class ViewHolder{
TextView tvTitle;
TextView tvContent;
} //实现ListView的监听器的接口
int visibleLastIndex = 0; //最后一个显示的索引
public class ListViewListener implements OnScrollListener{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//如果屏幕滑到最下面了,并且scrollState的状态为:滚动完毕之后ListView处于停止状态(手离开屏幕),
if(visibleLastIndex==myAdapter.getCount() && scrollState==OnScrollListener.SCROLL_STATE_IDLE){
new LoadDataThread().start();//如果满足上面的条件,此时,可以加载新数据了
}
} @Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
visibleLastIndex = firstVisibleItem+visibleItemCount-1; } } //额外开启一个线程,模拟加载数据
class LoadDataThread extends Thread{
@Override
public void run() {
initData();
try {
Thread.sleep(2000);//休眠两秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //新数据加载完成后,通过handle通知主线程,将这个新数据显示在UI界面上(因为涉及到线程安全问题)
handler.sendEmptyMessage(1);
}
} //handler为线程之间通信的桥梁
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch(msg.what){
case 1: //根据上面的提示,当Message为1,表示数据处理完了,可以通知主线程了
myAdapter.notifyDataSetChanged(); //这个方法一旦调用,UI界面就刷新了
break; default :
break;
}
} }; @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }

运行后,显示结果如下:

下图依次为:刚运行时、滑动到底部时、刷新之后的效果

三、总结:

  • 监听事件处理的接口:OnScrollListener
  • Adapter的刷新方法:notifyDataSetChanged()

【工程文件】

密码:bqsy
 

我的公众号

想学习代码之外的软技能?不妨关注我的微信公众号:生命团队(id:vitateam)。

扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:

Android UI组件----自定义ListView实现动态刷新的更多相关文章

  1. Android UI组件----ListView列表控件详解

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  2. Android常见UI组件之ListView(二)——定制ListView

    Android常见UI组件之ListView(二)--定制ListView 这一篇接上篇.展示ListView中选择多个项及实现筛选功能~ 1.在位于res/values目录下的strings.xml ...

  3. Android 高级UI设计笔记08:Android开发者常用的7款Android UI组件(转载)

    Android开发是目前最热门的移动开发技术之一,随着开发者的不断努力和Android社区的进步,Android开发技术已经日趋成熟,当然,在Android开源社区中也涌现了很多不错的开源UI项目,它 ...

  4. 第29讲 UI组件之 ListView与 BaseAdapter,SimpleAdapter

    第29讲 UI组件之 ListView与 BaseAdapter,SimpleAdapter 1.BaseAdapter BaseAdapter是Android应用程序中经常用到的基础数据适配器,它的 ...

  5. 第28讲 UI组件之 ListView和ArrayAdapter

    第28讲 UI组件之 ListView和ArrayAdapter 1. Adapter 适配器 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带.在常见的 ...

  6. 这是一个比较全的Android UI 组件

     Android组件及UI框架大全 原文地址:http://blog.csdn.net/smallnest/article/details/38658593 Android 是目前最流行的移动操作系统 ...

  7. [置顶] 安卓UI组件之ListView详解

    ListView是很常见的一个UI组件,在许多App中都很常用,其意思就是可滚动的列表,使用ListView必须使用Adapter(适配器),常用的适配器友谊ArrayAdapter,SimpleAd ...

  8. Android UI组件学习

    android.view.View类是全部UI组件的父类. 如果一些属性的内容本类找不到的时候一定要到父类之中进行查找. 所谓的学习组件的过程就是一个文档的查找过程. ※ Android之中所有的组件 ...

  9. android开发(34) 自定义 listView的分割线( 使用xml drawable画多条线)

    我遇到这样一个场景,我需要自定义 listView的分割线,而这个分割线是由两条线组成的,在使用xml drawable时遇到了困难. 注释:画两条线是为了实现 凹陷的效果,在绘图中一条暗线紧跟着一条 ...

随机推荐

  1. 我的Git教程 之 初始化本地库

    初始化本地库 前言:这个教程只适用于像我一样大致理解Git的原理,但是不太记得住Git命令的同学使用.所以具体原理只会提一下,具体可以参见Pro Git.同时,下面的操作需要先安装相应的Git工具,具 ...

  2. Bloom分类法

    美国教育心理学家Bloom将教育的目标分为六类,从低到高,依次是:知识(Knowledge).理解(comprehension).应用(application).分析(analysis).综合(syn ...

  3. pycharm 使用jupyter notebook 报错:'_xsrf' argument missing from POST

    出问题的关键点就在: 我用cmd启动的jupyter notebook,然后用pycham新建了一个jupyter notebook 结果 一直报错'_xsrf' argument missing f ...

  4. PMP备考指南之相关事项介绍

    本文已同步至 GitHub/Gitee/公众号,感兴趣的同学帮忙点波关注~ PMP是当今IT.通信.建筑.等高新技术行业的热门资格认证,无论是技术升级管理,还是管理者的能力提升,都离不开PMP的理论体 ...

  5. tomcat启动(Ⅷ)--请求最终目的地 getContainer().getPipeline().getFirst().invoke(request, response)

    当tomcat的Conector保存着StandardService实例,而StandardService保存着Container的实例 当Http11NioProcessor.process()方法 ...

  6. InterView之PHP

    PHP HTTP Keep-Alive的作用 作用 Keep-Alive:使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接.Web服务器 ...

  7. SpringMVC源码阅读:Controller中参数解析

    1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring ...

  8. 牛客网剑指offer java 全部题解

    经过数月的努力,终于更完了牛客网的66道剑指offer,以下的顺序和大家在牛客网的顺序是一样的(排序也花了不少时间),希望对大家找工作/提高算法能力能起到些许帮助. 每天一道剑指offer-二维数组中 ...

  9. 14.Iterator 和 for...of 循环

    Iterator 和 for...of 循环 Iterator 和 for...of 循环 Iterator(遍历器)的概念 JavaScript 原有的表示"集合"的数据结构,主 ...

  10. yum安装 指定安装目录

    yum -c /etc/yum.conf --installroot=/usr/local --releasever=/ install love