BaseHttpListActivity,几行代码搞定Android Http列表请求、加载和缓存

Android开发中,向服务器请求一个列表并显示是非常常见的需求,但实现起来比较麻烦,代码繁杂。

随着应用的更新迭代,这种需求越来越多,我渐渐发现了实现这种需求的代码的共同点。

于是我将Activity中http列表请求和加载的相同功能代码提取出来,作为这种Activity的基类,名为BaseHttpListActivity。

之后将缓存功能也集成在BaseHttpListActivity中,然后还根据业务需求衍生出了BaseHttpListFragment。

后来又有了从本地数据库加载列表的需求,就再次从BaseHttpListActivity提取出了BaseListActivity,负责列表显示和缓存。

BaseHttpListActivity只负责http请求,通过继承BaseHttpListActivity来实现显示和缓存。

有了BaseHttpListActivity和BaseHttpListFragment,原来用于实现http列表请求、加载和缓存的代码就变得非常简单了。

比如以下这个界面的主页:

列表是一个UserListFragment,支持下拉刷新上拉加载,第一次进入会直接显示刷新动画并加载数据。

  1 /**用户列表界面fragment
  2  * @author Lemon
  3  * @use new UserListFragment(),详细使用见.DemoFragmentActivity(initData方法内)
  4  * @must 查看 .HttpManager 中的@must和@warn
  5  *       查看 .SettingUtil 中的@must和@warn
  6  */
  7 public class UserListFragment extends BaseHttpListFragment<User, UserAdapter>
  8 implements OnItemClickListener, OnCacheCallBack<User> {
  9     //    private static final String TAG = "UserListFragment";
 10 
 11     //与Activity通信<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 12 
 13     public static final String ARGUMENT_RANGE = "ARGUMENT_RANGE";
 14 
 15     //与Activity通信>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 16 
 17 
 18     public static final int RANGE_ALL = HttpRequest.USER_LIST_RANGE_ALL;
 19     public static final int RANGE_RECOMMEND = HttpRequest.USER_LIST_RANGE_RECOMMEND;
 20 
 21     private int range = RANGE_ALL;
 22     @Override
 23     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 24         super.onCreateView(inflater, container, savedInstanceState);
 25 
 26         argument = getArguments();
 27         if (argument != null) {
 28             range = argument.getInt(ARGUMENT_RANGE, range);
 29         }
 30 
 31 
 32         initCache(this);
 33 
 34         //功能归类分区方法,必须调用<<<<<<<<<<
 35         initView();
 36         initData();
 37         initListener();
 38         //功能归类分区方法,必须调用>>>>>>>>>>
 39 
 40         lvBaseList.onRefresh();
 41 
 42         return view;
 43     }
 44 
 45 
 46     //UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 47 
 48     @Override
 49     public void initView() {//必须调用
 50         super.initView();
 51 
 52     }
 53 
 54     @Override
 55     public void setList(final List<User> list) {
 56         setList(list, new AdapterCallBack<UserAdapter>() {
 57 
 58             @Override
 59             public void refreshAdapter() {
 60                 adapter.refresh(list);
 61             }
 62             
 63             @Override
 64             public UserAdapter createAdapter() {
 65                 return new UserAdapter(context, list);
 66             }
 67         });
 68     }
 69 
 70 
 71 
 72     //UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83     //data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 84 
 85     @Override
 86     public void initData() {//必须调用
 87         super.initData();
 88 
 89     }
 90 
 91     @Override
 92     public void getListAsync(final int pageNum) {
 93         HttpRequest.getUserList(range, pageNum, 0, this);
 94     }
 95 
 96     @Override
 97     public List<User> parseArray(String json) {
 98         return Json.parseArray(json, User.class);
 99     }
100 
101     @Override
102     public Class<User> getCacheClass() {
103         return User.class;
104     }
105     @Override
106     public String getCacheGroup() {
107         return "range=" + range;
108     }
109     @Override
110     public String getCacheId(User data) {
111         return data == null ? null : "" + data.getId();
112     }
113 
114 
115 
116     //data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
117 
118 
119 
120 
121 
122 
123 
124 
125     //listener事件监听区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
126 
127 
128     @Override
129     public void initListener() {//必须调用
130         super.initListener();
131 
132         lvBaseList.setOnItemClickListener(this);
133     }
134 
135 
136 
137     //系统自带监听方法 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
138 
139     @Override
140     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
141         position -= lvBaseList.getHeaderViewsCount();
142         if (position < 0 || adapter == null || position >= adapter.getCount()) {
143             return;
144         }
145 
146         User user = adapter.getItem(position);    
147         if (BaseModel.isCorrect(user)) {//相当于 user != null && user.getId() > 0
148             toActivity(UserActivity.createIntent(context, user.getId()));
149         }
150     }
151 
152 
153     //类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
154 
155 
156     //类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
157 
158 
159 
160     //系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
161 
162 
163     //listener事件监听区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
164 
165 
166 
167 
168 
169 
170 
171 
172     //内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
173 
174 
175     //内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
176 
177 
178 }

getListAsync用于请求服务器列表数据,setList用于显示列表数据,

parseArray用于将服务器返回的json串转化为一个List<User>的方法。

通过initCache(this);初始化缓存,得到getCacheClass,getCacheGroup,getCacheId这3个缓存方法。

range相关代码是为了传入一个用户范围(或类型),让服务器返回需要范围的数据。

listener事件监听区代码里实现了点击列表项跳转至用户详情界面的功能。

剩下onCreateView和3个init方法维持着这个Fragment的框架。

原来Activity和Fragment中实现同样功能的上千行代码竟然能简化成这样!!!

而且如果是Fragment,有一个XListView默认布局,连layout都不再需要写了!!!

如果只需要从服务器加载一个列表,缓存和事件相关代码就可以去掉了;如果不需要限定数据范围,还可以去掉range相关代码。

  1 /**用户列表界面fragment
  2  * @author Lemon
  3  * @use new UserListFragment(),详细使用见.DemoFragmentActivity(initData方法内)
  4  * @must 查看 .HttpManager 中的@must和@warn
  5  *       查看 .SettingUtil 中的@must和@warn
  6  */
  7 public class UserListFragment extends BaseHttpListFragment<User, UserAdapter> {
  8     //    private static final String TAG = "UserListFragment";
  9 
 10     @Override
 11     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 12         super.onCreateView(inflater, container, savedInstanceState);
 13 
 14         //功能归类分区方法,必须调用<<<<<<<<<<
 15         initView();
 16         initData();
 17         initListener();
 18         //功能归类分区方法,必须调用>>>>>>>>>>
 19 
 20         lvBaseList.onRefresh();
 21 
 22         return view;
 23     }
 24 
 25 
 26     //UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 27 
 28     @Override
 29     public void setList(final List<User> list) {
 30         setList(list, new AdapterCallBack<UserAdapter>() {
 31 
 32             @Override
 33             public void refreshAdapter() {
 34                 adapter.refresh(list);
 35             }
 36             
 37             @Override
 38             public UserAdapter createAdapter() {
 39                 return new UserAdapter(context, list);
 40             }
 41         });
 42     }
 43 
 44 
 45 
 46     //UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57     //data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 58 
 59     @Override
 60     public void getListAsync(final int pageNum) {
 61         HttpRequest.getUserList(0, pageNum, 0, this);
 62     }
 63 
 64     @Override
 65     public List<User> parseArray(String json) {
 66         return Json.parseArray(json, User.class);
 67     }
 68 
 69 
 70     //data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79     //listener事件监听区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 80 
 81 
 82 
 83     //类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 84 
 85 
 86     //类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 87 
 88 
 89 
 90     //系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 91 
 92 
 93     //listener事件监听区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 94 
 95 
 96 
 97 
 98 
 99 
100 
101 
102     //内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
103 
104 
105     //内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
106 
107 
108 }

是不是更简洁了呢?

BaseHttpListActivity和BaseHttpListFragment已开源,依赖ZBLibrary(含使用方法)就可使用,下方附下载地址。

ZBLibrary-Android快速开发框架

下载地址(欢迎Star,欢迎Fork)

https://github.com/TommyLemon/Android-ZBLibrary

下载试用

ZBLibraryDemoApp.apk

原文地址:https://www.cnblogs.com/LemonStantard/p/5719477.html