Android 结合实际项目学会ListView局部刷新和相关知识《一》
转载本专栏博客,请注明出处:道龙的博客
最近在公司参与的项目中有一个界面需要做局部UI更新处理,把其化烦为简为Demoi形式写在这里。我们还是运行该Demo,知道ListView局部刷新的使用场景:(受时间限制,本篇就介绍这么多功能,下一篇会在这个Demo中加入更多的功能)
可以看到,点击每个Item的时候,ListView上的CheckBox会选中或取消选中。这里面用到知识点就是ListView的局部刷新,局部的意思就是脱离ListView,在每个Item位置进行更新UI操作。那么就从头一步步的学习如何实现这个功能:
一、实现基本功能。
模拟数据源,把最基本的功能先跑起来:
布局、自定义样式、自定义选择器都很简单,过多的代码就不再写了,文章只贴出业务逻辑重要的代码(文章最后会给出源代码可自行下载;由于实习公司使用的IDE还是Eclipse,本篇是基于eclipse写的)
主活动中代码也很常规简单:
public class MainActivity extends Activity { private ListView mListView;
List<ItemBean> mDatas = new ArrayList<ItemBean>();
private MyAdapter adapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.listview);
initData();
adapter = new MyAdapter();
mListView.setAdapter(adapter);
} /**模拟数据*/
private void initData() {
ItemBean mItemBean = null;
for (int i = 0; i < 40; i++) {
//集合添加20个对象
mItemBean = new ItemBean();
mItemBean.setText("学习ListView局部刷新"+i);
mItemBean.setResIcon(R.drawable.directory_icon);
mDatas.add(mItemBean);
}
} private class MyAdapter extends BaseAdapter{ @Override
public int getCount() {
if(mDatas != null){
return mDatas.size();
}
return 0;
} @Override
public Object getItem(int position) {
if(mDatas != null){
return mDatas.get(position);
}
return null;
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
holder = new ViewHolder();
convertView = View.inflate(getApplicationContext(), R.layout.file_item, null);
holder.ivIcon = (ImageView) convertView.findViewById(R.id.iv_icon);
holder.tvText = (TextView) convertView.findViewById(R.id.tv_name);
holder.ivOption = (ImageView) convertView.findViewById(R.id.iv_option);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
} //拿到数据
ItemBean mItem = (ItemBean) getItem(position);
//设置数据
holder.ivIcon.setImageResource(mItem.getResIcon());
holder.tvText.setText(mItem.getText());
return convertView;
} class ViewHolder{
ImageView ivIcon;
TextView tvText;
ImageView ivOption;
} }
}
此时运行程序:
接下来就对上边的常规代码做一下修饰了:
二、进入编辑模式
我们长按item的时候,希望整个布局改变一下进入编辑模式,让复选框图标展示,对应位置上ImageView图标消失,就可以这么写。
首先写一个方法,来控制布局的改变:
private boolean isEdit;
/**开始编辑模式*/
private void startEditMode() {
isEdit = true;//标志位置为true
//进入编辑模式,要改变IListView的界面
adapter.notifyDataSetChanged();
} /**结束编辑模式*/
private void stopEditMode(){
isEdit = false;
}
然后加入长按item的点击事件:
mListView.setOnItemLongClickListener(new OnItemLongClickListener() { @Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
startEditMode();
return true;//返回true后,mListView.setOnItemClickListener就不会再去调用
}
});
三、ListView中CheckBox选中取消,实现局部的刷新
定义一个item局部刷新的方法:
/**定义一个item局部刷新的方法*/
public void updateItemView(View ItemView){
CheckBox itemCb = (CheckBox) ItemView.findViewById(R.id.cb_checkbox);
if(itemCb.isChecked()){
//点击item,从选中状态调到未选中状态
itemCb.setChecked(false);
}else{
itemCb.setChecked(true);
}
}
在item的点击事件的时候,调用这个方法,即可完成checkbox的选中与取消:
mListView.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if(isEdit){
//如果是编辑模式
adapter.updateItemView(view);
}else{
//不是编辑模式,点击item做其他逻辑处理
Toast.makeText(getApplicationContext(), "当前item"+position, 0).show();
}
}
});
目前我们仅仅是实现了界面的刷新,但是cb的选中与取消要记录起来,点击了哪个item也要记录起来,这样才能做接下来的操作,选中cb执行什么样的任务,因此我们需要使用javabean,记录每次点击选中cb的操作:
具体的局部刷新修改后的方法如下:
/**定义一个item局部刷新的方法*///position,为了拿到当前item的对象,记录状态
public void updateItemView(View ItemView,int position){
position = position - mListView.getHeaderViewsCount();
ItemBean itemBean = mDatas.get(position);
CheckBox itemCb = (CheckBox) ItemView.findViewById(R.id.cb_checkbox);
if(itemCb.isChecked()){
//点击item,从选中状态调到未选中状态
itemCb.setChecked(false);
//记录当前item未选中状态
itemBean.setChecked(false);
}else{
itemCb.setChecked(true);
//记录当前item选中状态
itemBean.setChecked(true);
} //通过集合把选中的item的对象itemBean记录起来
List<ItemBean> selectDatas = new ArrayList<ItemBean>();
for (ItemBean info : mDatas) {
if(info.isChecked()){//当前的item是选中的
selectDatas.add(info);
}
} /**测试局部刷新*/
for (ItemBean itemBean2 : selectDatas) {
System.out.println(itemBean2.getText());
}
}
然后该方法肯定要被调用咯,在哪里调用?点击item的时候嘛,那就在注册item的点击事件稍作修改就可以了:
mListView.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if(isEdit){
//如果是编辑模式
adapter.updateItemView(view,position);
}else{
//不是编辑模式,点击item做其他逻辑处理
Toast.makeText(getApplicationContext(), "当前item"+position, 0).show();
}
}
});
但是这个时候还是有许多问题的,比如第二页的数据会复用第一页的数据,那就先解决这个bug。
只需要在getView里面,对item上边的cb重新复制就可以了。
if(isEdit){//是编辑模式
// Ui层面进入编辑模式
holder.checkBox.setVisibility(View.VISIBLE);
holder.ivOption.setVisibility(View.GONE); /**解决复用问题,对每一个item上的cb都重新赋值*/
if (mItem.isChecked()) {
holder.checkBox.setChecked(true);
} else {
holder.checkBox.setChecked(false);
} }else{
holder.checkBox.setVisibility(View.GONE);
holder.ivOption.setVisibility(View.VISIBLE);
}
四、根据是否编辑状态,修改顶部标题栏文本信息
接下来的逻辑稍微复杂,就是通过当前状态,来修改顶端的标题栏状态。
首先,长按进入编辑模式的时候,要显示当前选中多少个。需要一个标志位mSelectedCount。进入编辑模式,显示标题:
//修改标题栏
mTextView.setText(String.format("已选择了%d个", mSelectedCount));
那对于标志的增加减少要放到,updateItemView里面
if(itemCb.isChecked()){
//点击item,从选中状态调到未选中状态
itemCb.setChecked(false);
//记录当前item未选中状态
itemBean.setChecked(false); mSelectedCount --;
}else{
itemCb.setChecked(true);
//记录当前item选中状态
itemBean.setChecked(true); mSelectedCount ++;
}
由于逻辑稍微复杂,也不是要介绍局部刷新这个技术点的范围了,就不再继续往下写了。我把Demo全部代码,打包上传了。可以直接去下载,学习。看看一下后边的复杂逻辑是如何实现的:
明天或者后天加入更多功能后,再把资源上传吧,今天就到这里了~
Android 结合实际项目学会ListView局部刷新和相关知识《一》的更多相关文章
- Android listview局部刷新和模拟应用下载(zhu)
在android开发中,listview是比较常用的一个组件,在listview的数据需要更新的时候,一般会用notifyDataSetChanged()这个函数,但是它会更新listview中所有可 ...
- 转:android listview局部刷新和模拟应用下载
在 android开发中,listview是比较常用的一个组件,在listview的数据需要更新的时候,一般会用 notifyDataSetChanged()这个函数,但是它会更新listview中所 ...
- Android开源项目发现---ListView篇(持续更新)
资料转载地址:https://github.com/Trinea/android-open-project 1. android-pulltorefresh 一个强大的拉动刷新开源项目,支持各种控件下 ...
- 【转】Android开源项目发现---ListView篇(持续更新)
原文网址:http://blog.csdn.net/krislight/article/details/20211045 资料转载地址:https://github.com/Trinea/androi ...
- jquerymobile listview 局部刷新
function onSuccess(data, status) { data = $.trim(data); // alert(data); // return; if (data) { $('#l ...
- android:ListView的局部刷新
1.简介 对于android中的ListView刷新机制,大多数的程序员都是很熟悉的,修改或者添加adapter中的数据源之后,然后调用notifyDataSetChanged()刷新ListView ...
- ListView实现Item局部刷新
对于ListView数据的刷新大家都知道,改变Adapter的数据源,然后调用Adapter的notifyDateSetChanged()方法即可. 但是博主在做公司项目的时候,有个下载模块,因为可 ...
- Android 它们的定义ListView实现底部和页下拉刷新刷新的顶
在项目开发.由于数据量过大,寻呼需要加载或下拉刷新.为了缓解长期等待-time负载.这个博客的评论中被自己的定义实例ListView实现底部的下拉刷新页面正在加载结果和顶部. 其效果图: 一.List ...
- ListView的局部刷新
有的列表可能notifyDataSetChanged()代价有点高,最好能局部刷新. 局部刷新的重点是,找到要更新的那项的View,然后再根据业务逻辑更新数据即可. private void upda ...
随机推荐
- ConcurrentHashMap基于JDK1.8源码剖析
前言 声明,本文用的是jdk1.8 前面章节回顾: Collection总览 List集合就这么简单[源码剖析] Map集合.散列表.红黑树介绍 HashMap就是这么简单[源码剖析] LinkedH ...
- CentOS 7 安装Boost 1.61
1. 到官网下载最新版的boost,http://www.boost.org/users/history/version_1_61_0.html 2. 解压: tar zxvf boost_1_61_ ...
- 老刘 Yii2 源码学习笔记之 Component 类
类图关系 属性与方法 class Component extends BaseObject { private $_events = []; private $_eventWildcards = [] ...
- Django REST framework+Vue 打造生鲜超市(十)
十一.pycharm远程代码调试 第三方登录和支付,都需要有服务器才行(回调url),我们可以用pycharm去远程调试服务器代码 服务器环境搭建 以全新阿里云centos7系统为例: 11.1.阿里 ...
- 【Android】Android Studio3.1 Mac版本设置项目桌面icon
近来项目处于测试阶段,工作少了许多,就装了个最新的Android Studio,想写一下安卓.新建好项目,想设置个桌面的icon.我先准备好自己的icon图片,然后复制粘贴到res/mipmap-hd ...
- 0323-DOM基础操作
dom操作 1.找到元素(标签对象) 标签名: document.getElementsByTagName()[]; //返回的是数组类型,需要有下标来找内容 属性: document.getElem ...
- 高并发下,log4j日志打印行数导致的内存溢出问题
log4j日志打印时,如果将行数打印出来,在调用量极大的情况下,会出现内存溢出问题. log4j打印日志,打印行数时,行数是通过一个一个exception抛出,再极高调用量的情况下,内存会因为exce ...
- ios开发-程序压后台后,悄悄的抓取数据~~
我们使用某个app的时候,当我们将程序压到后台之后,我们希望它还能从服务器抓取一些数据,类似微博,微信,qq这些程序压后台 之后,我们依然能看到icon上显示未读数量.但是ios系统是伪多任务操作系统 ...
- [Luogu 3901]Difference
Description Input Output Sample Input 4 2 1 2 3 2 1 3 2 4 Sample Output Yes No HINT 题解 莫队.加个标记数组维护该数 ...
- 【BZOJ4196】【Noi2015】软件包管理器
原题传送门 题意: 给你一棵树,有2种操作: 1.使得某个点到根节点路径上的所有点权值赋为1. 2.使得某节点的子树中所有节点权值赋为0. 每次操作要求输出权值更改的节点个数. 解题思路: 显然是用树 ...