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时遇到了困难. 注释:画两条线是为了实现 凹陷的效果,在绘图中一条暗线紧跟着一条 ...
随机推荐
- 2018春招-今日头条笔试题-第一题(python)
题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) 解题思路: 要想得到输入的数字列中存在相隔为k的数,可以将输入的数字加上k,然后判断其在不在输入的数字列中即可. #-*- cod ...
- Spring Boot的listener简单使用
监听器(Listener)的注册方法和 Servlet 一样,有两种方式:代码注册或者注解注册 1.代码注册方式 通过代码方式注入过滤器 @Bean public ServletListene ...
- phpdocumentor生成代码注释文档(linux)
1,默认安装lnmp环境(php7),默认pear安装 2, pear channel-discover pear.phpdoc.org pear install phpdoc/phpDocume ...
- [转载]7款开源ERP系统比较
现在有许多企业将ERP项目,在企 业中没有实施好,都归咎于软件产品不好.其实,这只是你们的借口.若想要将ERP软件真正与企业融合一体,首先得考虑企业的自身情况,再去选择适合的 ERP软件. 如果你的企 ...
- 【jQuery源码】select方法
/** * select方法是Sizzle选择器包的核心方法之一,其主要完成下列任务: * 1.调用tokenize方法完成对选择器的解析 * 2.对于没有初始集合(即seed没有赋值)且是单一块选择 ...
- 机器学习--集成学习(Ensemble Learning)
一.集成学习法 在机器学习的有监督学习算法中,我们的目标是学习出一个稳定的且在各个方面表现都较好的模型,但实际情况往往不这么理想,有时我们只能得到多个有偏好的模型(弱监督模型,在某些方面表现的比较好) ...
- C#的SubString(int start,int end);
C#的SubString(); 例子: string str = "i am a girl"; string temp = str.Substring(2,2);//从索引2开始, ...
- oracle 比较日期相等
where to_char(date1, 'yyyymmdd')=to_char(date2,'yyyymmdd'); or where to_date(char1, 'yyyymmdd')=to_d ...
- 基于python的多线程暴破脚本
搭建了一个本地wordpress,写一个基于多线程异步I/O的暴力破解 1 测试 提交错误的表单数据时,查看请求参数 登录时发送的cookie 2 登录分析 经过多次测试,发现无论是输入正确的密码还是 ...
- MVC 基架不支持 Entity Framework 6 或更高版本 即 NuGet的几个小技巧
MVC 基架不支持 Entity Framework 6 或更高版本.有关详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=276833. 原因:mvc版 ...