1. import java.util.ArrayList;
  2. import java.util.List;
  3.  
  4. import com.heima.googleplay.holder.BaseHolder;
  5. import com.heima.googleplay.holder.MoreHolder;
  6. import com.heima.googleplay.manager.ThreadManager;
  7. import com.heima.googleplay.utils.UIUtils;
  8.  
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11. import android.widget.AbsListView.RecyclerListener;
  12. import android.widget.BaseAdapter;
  13. import android.widget.ListView;
  14.  
  15. public abstract class MyBaseAdapter<T> extends BaseAdapter implements
  16. RecyclerListener {
  17.  
  18. public ListView mListView;
  19.  
  20. public MyBaseAdapter(ListView mListView, List<T> mDatas) {
  21. this.mListView = mListView;
  22. // 初始化一个界面可见的holder
  23. mDisplayHolderLists = new ArrayList<BaseHolder>();
  24.  
  25. if (null != mListView) {
  26. // 设置listview的回收监听
  27. mListView.setRecyclerListener(this);
  28. }
  29. setData(mDatas);
  30. }
  31.  
  32. public List<T> mDatas;
  33. private BaseHolder holder;
  34. private List<BaseHolder> mDisplayHolderLists;
  35.  
  36. public void setData(List<T> mDatas) {
  37. this.mDatas = mDatas;
  38.  
  39. }
  40.  
  41. public List<T> getData() {
  42. return mDatas;
  43. }
  44.  
  45. @Override
  46. public int getCount() {
  47. // +1 表示添加一个特殊的条目
  48. return mDatas.size() + 1;
  49. }
  50.  
  51. @Override
  52. public Object getItem(int position) {
  53. // TODO Auto-generated method stub
  54. return mDatas.get(position);
  55. }
  56.  
  57. @Override
  58. public long getItemId(int position) {
  59. // TODO Auto-generated method stub
  60. return position;
  61. }
  62.  
  63. // 表示加载更多
  64. private final int MORE_ITEM_TYPE = 0;
  65. // 表示普通的数据类型
  66. private final int ITEM_VIEW_TYPE = 1;
  67. private MoreHolder moreHolder;
  68.  
  69. /**
  70. * 获取到item的类型
  71. *
  72. * @param position
  73. * @return
  74. */
  75. @Override
  76. public int getItemViewType(int position) {
  77. // 判断当前是否是最后一个条目
  78. if (position == getCount() - 1) {
  79. return MORE_ITEM_TYPE;
  80. } else {
  81. return getInnerItemViewType(position);
  82. }
  83. }
  84.  
  85. public int getInnerItemViewType(int position) {
  86. // TODO Auto-generated method stub
  87. return ITEM_VIEW_TYPE;
  88. }
  89.  
  90. /**
  91. * 获取到一共有多少中数据类型
  92. *
  93. * @return
  94. */
  95. @Override
  96. public int getViewTypeCount() {
  97. return super.getViewTypeCount() + 1;
  98. }
  99.  
  100. @Override
  101. public View getView(int position, View convertView, ViewGroup parent) {
  102. if (convertView != null) {
  103. holder = (BaseHolder) convertView.getTag();
  104. } else {
  105. if (getItemViewType(position) == MORE_ITEM_TYPE) {
  106. holder = getMoreHolder();
  107. } else {
  108. holder = getHolder();
  109. }
  110.  
  111. }
  112. if (getItemViewType(position) == ITEM_VIEW_TYPE) {
  113. holder.setData(mDatas.get(position));
  114. }
  115.  
  116. // 把所有的holder全部丢入mDisplayHolderLists
  117. mDisplayHolderLists.add(holder);
  118. return holder.getRootView();
  119. }
  120. /**
  121. * 获取更多的holder
  122. * @return
  123. */
  124. private BaseHolder getMoreHolder() {
  125. if(moreHolder == null){
  126. moreHolder = new MoreHolder(hasMore(),this);
  127. }
  128.  
  129. return moreHolder;
  130. }
  131. /**
  132. * 表示有更多的数据
  133. * @return
  134. */
  135. public boolean hasMore() {
  136. // TODO Auto-generated method stub
  137. return true;
  138. }
  139.  
  140. public abstract BaseHolder getHolder();
  141.  
  142. /**
  143. * 当listview回收的时候调用当前的方法
  144. */
  145. @Override
  146. public void onMovedToScrapHeap(View view) {
  147. System.out.println("我被回收了.....");
  148. if (null != view) {
  149. BaseHolder holder = (BaseHolder) view.getTag();
  150. if (null != holder) {
  151. synchronized (mDisplayHolderLists) {
  152. mDisplayHolderLists.remove(holder);
  153. }
  154.  
  155. }
  156. }
  157.  
  158. }
  159. private boolean isLoading = false;
  160. /**
  161. * 加载更多
  162. */
  163. public void loadMore() {
  164. if(!isLoading){
  165. isLoading = true;
  166. ThreadManager.getLongPool().execute(new Runnable() {
  167.  
  168. @Override
  169. public void run() {
  170. final List list = onLoadMore();
  171. UIUtils.runInMainThread(new Runnable() {
  172.  
  173. @Override
  174. public void run() {
  175. if(null == list){
  176. //如果服务器返回的数据等于null。那么设置一个错误状态
  177. getMoreHolder().setData(MoreHolder.ERROR);
  178. }else if(list.size() < 20){
  179. //如果服务器返回的数据小于20条。那么设置没有更多数据的状态
  180. getMoreHolder().setData(MoreHolder.NO_MORE);
  181. }else{
  182. getMoreHolder().setData(MoreHolder.HAS_MORE);
  183. }
  184.  
  185. if(null != list){
  186. if(null !=mDatas){
  187. mDatas.addAll(list);
  188. }else{
  189. setData(list);
  190. }
  191. }
  192. //刷新界面
  193. notifyDataSetChanged();
  194. isLoading = false;
  195. }
  196. });
  197.  
  198. }
  199. });
  200. }
  201.  
  202. }
  203.  
  204. protected abstract List onLoadMore();
  205.  
  206. }

MyBaseAdapter

  1. package com.heima.googleplay.widget;
  2.  
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5.  
  6. import com.heima.googleplay.R;
  7. import com.heima.googleplay.manager.ThreadManager;
  8. import com.heima.googleplay.utils.UIUtils;
  9.  
  10. import android.content.Context;
  11. import android.util.AttributeSet;
  12. import android.view.View;
  13. import android.widget.FrameLayout;
  14. /**
  15. *
  16. *
  17. * ============================================================
  18. **/
  19. public abstract class LoadingPage extends FrameLayout {
  20. //默认状态
  21. private final int UN_LOADING = 1;
  22. //加载状态
  23. private final int LOADING = 2;
  24. //加载失败状态
  25. private final int ERROR = 3;
  26. //加载成功。然后服务器没有返回数据
  27. private final int EMPTY = 4;
  28. //加载成功的状态
  29. private final int SUCCESS = 5;
  30. //用来记录某种状态
  31. private int mState;
  32. private View mLoadingView;
  33. private View mErrorView;
  34. private View mEmptyView;
  35.  
  36. private View mSuccessView;
  37. public LoadingPage(Context context, AttributeSet attrs, int defStyle) {
  38. super(context, attrs, defStyle);
  39. init();
  40. }
  41.  
  42. private void init() {
  43. //首先赋值
  44. mState = UN_LOADING;
  45.  
  46. mLoadingView = createLoadingView();
  47.  
  48. if(null != mLoadingView){
  49. addView(mLoadingView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
  50. }
  51.  
  52. mErrorView = createErrorView();
  53.  
  54. if(null != mErrorView){
  55. addView(mErrorView,new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
  56. }
  57.  
  58. mEmptyView = createEmptyView();
  59.  
  60. if(null != mEmptyView ){
  61. addView(mEmptyView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
  62. }
  63.  
  64. showSafePage();
  65.  
  66. }
  67.  
  68. private void showSafePage() {
  69. UIUtils.runInMainThread(new Runnable() {
  70.  
  71. @Override
  72. public void run() {
  73. showPage();
  74.  
  75. }
  76. });
  77.  
  78. }
  79.  
  80. protected void showPage() {
  81. if(null != mLoadingView){
  82. mLoadingView.setVisibility(mState == UN_LOADING || mState == LOADING ? View.VISIBLE : View.INVISIBLE);
  83. }
  84.  
  85. if(null != mErrorView){
  86. mErrorView.setVisibility(mState == ERROR ? View.VISIBLE : View.INVISIBLE);
  87. }
  88.  
  89. if(null != mEmptyView){
  90. mEmptyView.setVisibility(mState == EMPTY ? View.VISIBLE : View.INVISIBLE);
  91. }
  92.  
  93. if(null == mSuccessView && mState == SUCCESS ){
  94. mSuccessView = createSuccessView();
  95. addView(mSuccessView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
  96. }
  97. if(null != mSuccessView){
  98. mSuccessView.setVisibility(mState == SUCCESS ? View.VISIBLE : View.INVISIBLE);
  99. }
  100. }
  101.  
  102. public abstract View createSuccessView();
  103.  
  104. private View createEmptyView() {
  105. // TODO Auto-generated method stub
  106. return UIUtils.inflate(R.layout.loading_page_empty);
  107. }
  108.  
  109. private View createErrorView() {
  110. // TODO Auto-generated method stub
  111. return UIUtils.inflate(R.layout.loading_page_error);
  112. }
  113.  
  114. private View createLoadingView() {
  115. // TODO Auto-generated method stub
  116. return UIUtils.inflate(R.layout.loading_page_loading);
  117. }
  118.  
  119. public LoadingPage(Context context, AttributeSet attrs) {
  120. super(context, attrs);
  121. init();
  122. }
  123.  
  124. public LoadingPage(Context context) {
  125. super(context);
  126. init();
  127. }
  128. // //加载失败状态
  129. // private final int ERROR = 3;
  130. // //加载成功。然后服务器没有返回数据
  131. // private final int EMPTY = 4;
  132. // //加载成功的状态
  133. // private final int SUCCESS = 5;
  134. public enum LoadResult{
  135. ERROR(3),EMPTY(4),SUCCESS(5);
  136. int value ;
  137. LoadResult(int value){
  138. this.value = value;
  139. }
  140. public int getValue() {
  141. return value;
  142. }
  143. }
  144.  
  145. private class LoadTask implements Runnable{
  146.  
  147. @Override
  148. public void run() {
  149. final LoadResult result = Load();
  150. UIUtils.runInMainThread(new Runnable() {
  151.  
  152. @Override
  153. public void run() {
  154.  
  155. mState = result.getValue();
  156.  
  157. showPage();
  158. }
  159. });
  160.  
  161. }
  162.  
  163. }
  164.  
  165. public void show() {
  166. if(mState == ERROR || mState == EMPTY){
  167. mState = UN_LOADING;
  168. }
  169.  
  170. if(mState == UN_LOADING){
  171. mState = LOADING;
  172.  
  173. LoadTask task = new LoadTask();
  174. ThreadManager.getLongPool().execute(task);
  175. // ExecutorService service = Executors.newFixedThreadPool(3);
  176. // LoadTask task = new LoadTask();
  177. // service.execute(task);
  178. }
  179. showSafePage();
  180. }
  181.  
  182. public abstract LoadResult Load() ;
  183.  
  184. }

LoadingPage

android 应用架构随笔三(ListView)的更多相关文章

  1. android 应用架构随笔六(Loading加载页面)

    import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import com.heima ...

  2. android 应用架构随笔四(View、ViewGroup)

    View表示了用户界面的基本构建模块. 一个View占用了屏幕上的一个矩形区域并且负责界面绘制和事件处理.手机屏幕上所有看得见摸得着的都是View. Activity是四大组件中唯一一个用来和用户进行 ...

  3. android 应用架构随笔五(ActionBar与侧滑菜单DrawerLayout)

    ActionBar(V7)的添加非常简单,只需要在AndroidManifest.xml中指定Application或Activity的theme是Theme.Holo或其子类就可以了,在Androi ...

  4. android 应用架构随笔二(定义BaseApplication并配置Application)

    定义BaseApplication并配置Application import android.app.Application; import android.os.Handler; /** * * = ...

  5. android 应用架构随笔一(架构搭建)

    1.拷贝积累utils以及PagerTab类 2.定义BaseApplication类 3.定义BaseActivity类 4.改写MainActivity 5.定义布局文件 6.定义BaseFrag ...

  6. android 项目学习随笔三(Fragment )

    1.在主页面(activity引用Fragment )的布局文件中定义FrameLayout ,加载Fragment  <FrameLayout xmlns:android="http ...

  7. Android实训案例(三)——实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果!

    Android实训案例(三)--实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果! 感叹离春节将至,也同时感叹时间不等人,一年又一年,可是我依然是android道路上的小菜鸟,这篇讲 ...

  8. Android应用架构

    Android开发生态圈的节奏非常之快.每周都会有新的工具诞生,类库的更新,博客的发表以及技术探讨.如果你外出度假一个月,当你回来的时候可能已经发布了新版本的Support Library或者Play ...

  9. 【译】Android应用架构

    Android开发生态圈的节奏非常之快.每周都会有新的工具诞生,类库的更新,博客的发表以及技术探讨.如果你外出度假一个月,当你回来的时候可能已经发布了新版本的Support Library或者Play ...

随机推荐

  1. mongoDB命令

    . getLastError db.runCommand({getLastError:}) . buildInfo //返回mongoDB的服务器版本号和操作系统类型 db.runCommand({} ...

  2. C++经典编程题#3:数字求和

    总时间限制:  1000ms 内存限制:  65536kB 描述 给定一个正整数a,以及另外的5个正整数,问题是:这5个整数中,小于a的整数的和是多少? 输入 输入一行,只包括6个小于100的正整数, ...

  3. 我的工具箱之MyEclipse9.1

    下载地址:http://pan.baidu.com/s/1bbuN1s 这个工具是用来开发Java程序,自带JDK和Tomcat,功能全面周到,使用方便. 市面上MyEclipse版本很多,但都需要破 ...

  4. Objective-C的对象模型

    Objective-C是一门面向对象,并且在C的基础上加入了Smalltalk式的消息机制而形成的编程语言,它主要被苹果公司用于开发Mac OS X和iOS操作系统.既然Objective-C是面向对 ...

  5. 11种dialogBox样式打包开源,逐一详解

    期待已久,APICloud官方总算把各种提示样式给封装了,再也不用苦逼的自己各种被虐着封装自定义样式了.这个分享我把 dialogBox 模块的 11 个样式分别实现个简单的效果,其中将 alert ...

  6. APICloud十一月线下活动(杭州、上海)

    阿里云创业大学 ——APICloud/银杏谷移动课堂[杭州站] 时间:2015年11月28日13:30-16:30 地点:文三路华星时代广场A座3楼银杏谷1024孵化器 主办:APICloud.阿里云 ...

  7. 30天,APP创业从0到1【7.26苏州站】

    活动概况 时间:2015年7月26日13:30-16:30 地点:创客巢(苏州吴中区玉山路646号金枫广告产业园B栋4楼) 主办:APICloud.融云.鱼多多 网址:www.apicloud.com ...

  8. 如何在SQLServer中处理每天四亿三千万记录

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  9. 使用Storm实现实时大数据分析

    摘要:随着数据体积的越来越大,实时处理成为了许多机构需要面对的首要挑战.Shruthi Kumar和Siddharth Patankar在Dr.Dobb’s上结合了汽车超速监视,为我们演示了使用Sto ...

  10. linux下如何启动/停止/重启mysql:

    一.启动方式1.使用linux命令service 启动:service mysqld start2.使用 mysqld 脚本启动:/etc/inint.d/mysqld start3.使用 safe_ ...