Android UI组件----自定义ListView实现动态刷新
【声明】
欢迎转载,但请保留文章原始出处→_→
生命壹号: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()
【工程文件】
我的公众号
想学习代码之外的软技能?不妨关注我的微信公众号:生命团队(id:vitateam)。
扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:

Android UI组件----自定义ListView实现动态刷新的更多相关文章
- Android UI组件----ListView列表控件详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...
- Android常见UI组件之ListView(二)——定制ListView
Android常见UI组件之ListView(二)--定制ListView 这一篇接上篇.展示ListView中选择多个项及实现筛选功能~ 1.在位于res/values目录下的strings.xml ...
- Android 高级UI设计笔记08:Android开发者常用的7款Android UI组件(转载)
Android开发是目前最热门的移动开发技术之一,随着开发者的不断努力和Android社区的进步,Android开发技术已经日趋成熟,当然,在Android开源社区中也涌现了很多不错的开源UI项目,它 ...
- 第29讲 UI组件之 ListView与 BaseAdapter,SimpleAdapter
第29讲 UI组件之 ListView与 BaseAdapter,SimpleAdapter 1.BaseAdapter BaseAdapter是Android应用程序中经常用到的基础数据适配器,它的 ...
- 第28讲 UI组件之 ListView和ArrayAdapter
第28讲 UI组件之 ListView和ArrayAdapter 1. Adapter 适配器 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带.在常见的 ...
- 这是一个比较全的Android UI 组件
Android组件及UI框架大全 原文地址:http://blog.csdn.net/smallnest/article/details/38658593 Android 是目前最流行的移动操作系统 ...
- [置顶] 安卓UI组件之ListView详解
ListView是很常见的一个UI组件,在许多App中都很常用,其意思就是可滚动的列表,使用ListView必须使用Adapter(适配器),常用的适配器友谊ArrayAdapter,SimpleAd ...
- Android UI组件学习
android.view.View类是全部UI组件的父类. 如果一些属性的内容本类找不到的时候一定要到父类之中进行查找. 所谓的学习组件的过程就是一个文档的查找过程. ※ Android之中所有的组件 ...
- android开发(34) 自定义 listView的分割线( 使用xml drawable画多条线)
我遇到这样一个场景,我需要自定义 listView的分割线,而这个分割线是由两条线组成的,在使用xml drawable时遇到了困难. 注释:画两条线是为了实现 凹陷的效果,在绘图中一条暗线紧跟着一条 ...
随机推荐
- Java之IO(十)Reader和Writer
转载请注明源出处:http://www.cnblogs.com/lighten/p/7071733.html 1.前言 之前的章节已经将Java8的io包中的字节流介绍完毕了.本章开始介绍Java的I ...
- Chapter 3 Phenomenon——11
"I'm completely fine, Char — Dad," I sighed. "There's nothing wrong with me." “我 ...
- 三篇文章了解 TiDB 技术内幕 - 说存储(转)
引言 数据库.操作系统和编译器并称为三大系统,可以说是整个计算机软件的基石.其中数据库更靠近应用层,是很多业务的支撑.这一领域经过了几十年的发展,不断的有新的进展. 很多人用过数据库,但是很少有人实现 ...
- python如何帮我在投资中获取更高收益
搞技术的大都比较纯粹,比较实在,除了工资之外基本就没有别的收入了(少部分人能接外包赚外块).或许是迫于生活的压力,或许是不甘于固定的工资,或许是出于技术人骨子里的好奇,亦或是这几年关于理财投资的大力宣 ...
- Oracle 12c 建表空间语句
create tablespace TBS_DYS datafile 'D:/Oracle_12c/app/dingyingsi/oradata/dingyingsi/TBS_DYS.ba' size ...
- Linux 文件内容查看工具介绍-cat,less,more,tail,head
Linux 文件内容查看工具介绍 作者:北南南北来自:LinuxSir.Org摘要: 本文讲述几种常用文件内容的查看工具,比如cat.more.less.head.tail等,把这些工具最常用的参数. ...
- after_create and after_commit
A relational database, like mysql, provides transactions to wrap several operations in one unit, mak ...
- win8.1弹框
在winform或者wp8中用MessageBox.Show()弹框,但是wp8.1中已经不存在了 private async void btn_Click(object sender, Routed ...
- nodejs --- 上传文件并保存到磁盘
先复习下整个请求的过程 const express = require('express'); const static = require('express-static'); const cook ...
- 虚拟机VirtualBox安装
一.安装VirtualBox 下载地址:https://www.virtualbox.org/wiki/Downloads 一直点击下一步到结束就行了. 二.启动报错:“获取 VirtualBox C ...