ListView之重构


  • 1 目标

listview是使用率非常高的,尽量少的代码完成listview功能,这里设计一种基于网络的可上下刷新的listview:【NetRefreshListView】


  • 2 API调用

某个Activity使用【NetRefreshListView】时,只需要完成下面两个API调用

  • 2.1 初始化
1 NetRefreshListView  netRefreshListView = new NetRefreshListView<CourseBean>(ConstUtil.COURSE_LIST, R.layout.homev4_listitem_hotcourse_layout, this);
2 netRefreshListView.refresh();

其中构造函数的解释:

1  /**
2      * 构造函数:
3      * 1 netype: 网络URL
4      * 2 adapterres:adapter的资源id
5      * 3 INetRefreshListListener:监听器,用于获取activit相关信息*/
6     public NetRefreshListView(String netype, int adapterres, final INetRefreshListListener in_listener) {}

  • 2.2 实现接口
 1 public interface INetRefreshListListener {
 2         void onItemClickListener(int position, String netype); //点击时处理逻辑
 3
 4         void netList(int index, String netype); //获取第几页的数据
 5
 6         void isEnd(String netype); //已经到了尾部
 7
 8         int getDataTotalSize(String netype); //获取所有数据的数量
 9
10         void drawUIWithList(String netype); //网络有数据时,渲染UI
11
12         void drawUIWithEmptyList(String netype);//网络无数据时,渲染UI
13
14         Context getContext();  //获取上下文
15
16         void setAdapterConvert(BaseViewHolder viewHolder, Object t, String jjNetype); //初始化adapter
17
18         PullToRefreshListView onGetPullToRefreshListView(String netype); //获取UI级list
19     }

  • 3 API特点

该API依赖PullToRefreshListView,实现顶部尾部下拉刷新,再结合xutils 的网络访问便可以轻松实现listview功能,相比pulltorefreshlistview,这次重构有以下几个优点:

3.1 不再写:判断是否重新加载、更多加载之类的代码,节省50行代码量

3.2 精简网络访问的API,只需要调用【netlist】方法便可以

3.3 精简adapter,只需复写【setAdapterConvert】方法便可以,不再每次额外新建一个adapter类



4 未考虑地方

4.1 listview的局部数据更新

4.2 判断是否加载更多的方法【getDataTotalSize】,有待继续完善,不能适配所有,这里之所以这样做,因为后台服务端给提供一个total字段来识别之。



5 源码

  1 package com.huisharing.pbook.controller.util;
  2
  3 import android.content.Context;
  4 import android.os.Handler;
  5 import android.os.Message;
  6 import android.util.Log;
  7 import android.view.View;
  8 import android.widget.AdapterView;
  9
 10 import com.huisharing.pbook.adapter.base.BaseViewHolder;
 11 import com.huisharing.pbook.adapter.base.MyBaseAdapter;
 12 import com.huisharing.pbook.widget.PullToRefreshBase;
 13 import com.huisharing.pbook.widget.PullToRefreshListView;
 14
 15 import java.lang.reflect.Constructor;
 16 import java.util.ArrayList;
 17 import java.util.List;
 18
 19 /**
 20  * 基于网络获取的listview
 21  * Created by Administrator on 2016/8/13.
 22  */
 23 public class NetRefreshListView<T> {
 24     PullToRefreshListView listView;
 25     MyBaseAdapter adapter;
 26     List list = new ArrayList<>(4);
 27     INetRefreshListListener m_listener;
 28     private int index = 1;
 29     private boolean isRefresh = true;
 30     private String jjNetype;
 31
 32     final static int DRAWITHCOURSE = 1;
 33     final static int DRAWITHEMPTY = 2;
 34     private Handler handler = new Handler() {
 35         public void handleMessage(Message msg) {
 36             switch (msg.what) {
 37                 case DRAWITHCOURSE:
 38                     m_listener.drawUIWithList(jjNetype);
 39                     if (isRefresh) {
 40                         list.clear();
 41                     }
 42                     list.addAll((List) msg.obj);
 43                     adapter.notifyDataSetChanged();
 44                     break;
 45
 46                 case DRAWITHEMPTY:
 47                     m_listener.drawUIWithEmptyList(jjNetype);
 48                     break;
 49
 50             }
 51         }
 52     };
 53
 54
 55     public List<T> getAdapterList() {
 56         return adapter.getList();
 57     }
 58
 59     public void doUIAfternet(List list) {
 60         if (list == null || list.size() <= 0) {
 61             handler.sendEmptyMessage(DRAWITHEMPTY);
 62         } else {
 63             Message msg = new Message();
 64             msg.what = DRAWITHCOURSE;
 65             msg.obj = list;
 66             handler.sendMessage(msg);
 67         }
 68     }
 69
 70     public interface INetRefreshListListener {
 71         void onItemClickListener(int position, String netype); //点击时处理逻辑
 72
 73         void netList(int index, String netype); //获取第几页的数据
 74
 75         void isEnd(String netype); //已经到了尾部
 76
 77         int getDataTotalSize(String netype); //获取所有数据的数量
 78
 79         void drawUIWithList(String netype); //网络有数据时,渲染UI
 80
 81         void drawUIWithEmptyList(String netype);//网络无数据时,渲染UI
 82
 83         Context getContext();  //获取上下文
 84
 85         void setAdapterConvert(BaseViewHolder viewHolder, Object t, String jjNetype); //初始化adapter
 86
 87         PullToRefreshListView onGetPullToRefreshListView(String netype); //获取UI级list
 88     }
 89
 90     class ListAdapter extends MyBaseAdapter<T> {
 91
 92         public ListAdapter(Context context, int resource, List<T> list) {
 93             super(context, resource, list);
 94         }
 95
 96         @Override
 97         public void setConvert(BaseViewHolder viewHolder, T t) {
 98             m_listener.setAdapterConvert(viewHolder, t, jjNetype);
 99         }
100     }
101
102     /**
103      * 构造函数:
104      * 1 netype: 网络URL
105      * 2 adapterres:adapter的资源id
106      * 3 INetRefreshListListener:监听器,用于获取activit相关信息
107      */
108     public NetRefreshListView(String netype, int adapterres, final INetRefreshListListener in_listener) {
109         try {
110             m_listener = in_listener;
111             listView = in_listener.onGetPullToRefreshListView(netype);
112
113             Constructor cons = ListAdapter.class.getConstructor(NetRefreshListView.class, Context.class, int.class, List.class);
114             adapter = (ListAdapter) cons.newInstance(new Object[]{this, m_listener.getContext(), adapterres, list});
115
116             jjNetype = netype;
117             listView.getRefreshableView().setAdapter(adapter);
118             listView.getRefreshableView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
119                 @Override
120                 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
121                     m_listener.onItemClickListener(position, jjNetype);
122                 }
123             });
124
125             listView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener() {
126                 @Override
127                 public void onRefresh() {
128                     if (listView.hasPullFromTop() || (!listView.hasPullFromTop() && m_listener.getDataTotalSize(jjNetype) <= 0)) {
129                         index = 1;
130                         isRefresh = true;
131                         m_listener.netList(index, jjNetype);
132                     } else {
133                         isRefresh = false;
134                         if (!next()) {
135                             listView.onRefreshComplete();
136                             m_listener.isEnd(jjNetype);
137                             return;
138                         }
139                         index++;
140                         m_listener.netList(index, jjNetype);
141                     }
142                     listView.onRefreshComplete();
143                 }
144             });
145         } catch (Exception e) {
146             Log.e("GXT", e.getMessage());
147         }
148     }
149
150     public void refresh() {
151         index = 1;
152         isRefresh = true;
153         m_listener.netList(index, jjNetype);
154     }
155
156
157     private boolean next() {
158         if (list.size() < m_listener.getDataTotalSize(jjNetype)) {
159             return true;
160         } else {
161             return false;
162         }
163     }
164
165 }

时间: 2024-10-03 14:41:44

ListView之重构的相关文章

android之ListView分组及字母索引导航(2)重构-接口

上篇文章对listView 分组和字母索引导航的实现思路做了分析,并依照思路一步步实现,到最后已经较好的实现了全部功能.但是仔细研究就会发现其实现不够好,主要问题: 1.               对于一个使用范围比较广泛的布局,以上实现不够通用,尤其是Bo中需加上一些多余的字段,这些字字段本身并没有意义. 2.               代码都糅合在activity中. 针对以上两点做一些代码重构.首先我们把其优化为一个通用的activity.这样做成通用的View就很容易:然后对代码进行

TwinklingRefreshLayout 小而强大的刷新控件,自带顺滑的越界回弹,v1.04 版精心重构,完美发布啦!

TwinklingRefreshLayout v1.04 版精心重构,优化 UI.刷新及越界动画效果,修复众多 bug,完美发布! TwinklingRefreshLayout延伸了Google的SwipeRefreshLayout的思想,不在列表控件上动刀,而是使用一个ViewGroup来包含列表控件,以保持其较低的耦合性和较高的通用性.其主要特性有: 支持RecyclerView.ScrollView.AbsListView系列(ListView.GridView).WebView以及其它可

ListView 控件

一.显示数据 1.视图 -----小三角--视图-Details 2.设置列头 ----右键--编辑列 --添加 编辑列右边的属性:Text是列名,DisplayIndex是显示列的顺序 3.添加行数据 ----右键--编辑项--添加 编辑项右边的属性:Text设置第一列的数据,SubItems集合设置其余列的数据 4.编写实体类和数据访问类(同ADO.NET),并进行属性扩展 5.读取数据并显示 注意:实例化 ListViewItem li = new ListViewItem(); a =

listview控件及其与数据库的连接

一.显示数据 1.视图 -----小三角--视图-Details,该选项最常用,选中之后会以表格样式呈现. 2.设置列头 ----右键--编辑列 --添加 先编辑列,再编辑项 编辑列右边的属性:Text是列名,DisplayIndex是显示列的顺序 3.添加行数据 ----右键--编辑项--添加 编辑项右边的属性:Text设置第一列的数据,SubItems集合设置其余列的数据////上边是手动添加随意数据 如果是用数据库的数据的话可以在数据库的数据之前额外添加一列序号放在li.Text里,方便查

Android 项目重构之路:实现篇

前两篇文章<Android项目重构之路:架构篇>和<Android项目重构之路:界面篇>已经讲了我的项目开始搭建时的架构设计和界面设计,这篇就讲讲具体怎么实现的,以实现最小化可用产品(MVP)的目标,用最简单的方式来搭建架构和实现代码. IDE采用Android Studio,Demo实现的功能为用户注册.登录和展示一个券列表,数据采用我们现有项目的测试数据,接口也是我们项目中的测试接口. 项目搭建 根据架构篇所讲的,将项目分为了四个层级:模型层.接口层.核心层.界面层.四个层级之

android ListView内数据的动态添加与删除

main.xml 文件: [java] view plaincopy <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height=&q

Android 项目重构之路:界面篇

在前一篇文章<Android项目重构之路:架构篇>中已经简单说明了项目的架构,将项目分为了四个层级:模型层.接口层.核心层.界面层.其中,最上层的界面,是变化最频繁的一个层面,也是最复杂最容易出问题的一个层面,如果规划不好,很容易做着做着,又乱成一团了. 要规划好界面层,至少应该遵循几条基本的原则: 保持规范性:定义好开发规范,包括书写规范.命名规范.注释规范等,并按照规范严格执行: 保持单一性:布局就只做布局,内容就只做内容,各自分离好:每个方法.每个类,也只做一件事情: 保持简洁性:保持代

简单的横向ListView实现(version 3.0)

版本2只是简单的实现了当手指按下的时候listView的Item向左移动一定的距离,并没有随着手指的左右移动而左右滚动,在这个版本3.0中将会实现随着手指的移动而滚动的目标:当手指向左移动的时候,listView向左滚动:当手指向右移动的时候,listView向右滚动:在开始进入正题之前,先说说预备的知识和涉及到的方法. 在version2.0之前添加View的时候用的都是addView最终辗转调用了addViewInner方法,经过查询viewGroup的源码发现有一个addViewInLay

Android源码之ListView的适配器模式

模式的定义 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 使用场景 用电源接口做例子,笔记本电脑的电源一般都是接受5V的电压,但是我们生活中的电线电压一般都是220V的输出.这个时候就出现了不匹配的状况,在软件开发中我们称之为接口不兼容,此时就需要适配器来进行一个接口转换.在软件开发中有一句话正好体现了这点:任何问题都可以加一个中间层来解决.这个层我们可以理解为这里的Adapter层,通过这层来进行一个接口转换就达到了兼容