• 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

  • 相关阅读:
    UVa10779
    UVa10779
    C++ 内存管理学习笔记
    c++ 学习笔记
    AcWing 275 传纸条
    I
    Tree HDU6228
    Lpl and Energy-saving Lamps
    C
    Secret Poems
  • 原文地址:https://www.cnblogs.com/LemonStantard/p/5719477.html
Copyright © 2020-2023  润新知