你的位置:首页 > 软件开发 > 操作系统 > 【原创】StickHeaderListView的简单实现,解决footerView问题

【原创】StickHeaderListView的简单实现,解决footerView问题

发布时间:2016-06-28 19:00:06
1、前言: 前几天用了GitHub上se.emilsjolander.stickylistheaders这个组件,然后发现这个组件的listview不能添加footerView,加了footer后,滑倒footer的时候head会消失,与我项目中的需求不符。于是就自己写了一个 ...

【原创】StickHeaderListView的简单实现,解决footerView问题

1、前言:

 

前几天用了GitHub上se.emilsjolander.stickylistheaders这个组件,然后发现这个组件的listview不能添加footerView,加了footer后,滑倒footer的时候head会消失,与我项目中的需求不符。

于是就自己写了一个StickHeaderListView,实现比较简单,做法和stickylistheaders基本相同只是没有封装那么多功能,可以添加footer但不能添加header,有需要的同学可以拿去改良后用。

另外由于是临时写的一个组件,代码没做什么优化,如果有想法可以提点意见,谢谢!

 

2、示例效果:

【原创】StickHeaderListView的简单实现,解决footerView问题

 

3、组件源码:

 1 /** 2  * 带头部固定的列表 3  * Created by shengdong.huang on 2016/6/24. 4 */ 5 public class StickHeaderListView extends FrameLayout { 6  7   /** 页面引用 */ 8   protected Context context; 9   /** 列表视图 */ 10   protected ListView listView; 11   /** 适配器 */ 12   protected StickHeaderAdapter adapter; 13   /** 头部布局 */ 14   protected FrameLayout headLayout; 15   /** 滚动** */ 16   protected OnScrollListener listener; 17   /** 提供Adapter响应的观察者 */ 18   protected DataSetObserver mDataSetObserver = new DataSetObserver() { 19     @Override 20     public void onChanged() { 21       if (listView != null && headLayout != null && adapter != null) { 22         refreshHead(listView.getFirstVisiblePosition(), true); 23       } 24     } 25  26     @Override 27     public void onInvalidated() { 28     } 29   }; 30  31   /** 32    * 滚动** 33   */ 34   protected AbsListView.OnScrollListener scrollListener = new AbsListView.OnScrollListener() { 35  36     @Override 37     public void onScrollStateChanged(AbsListView view, int scrollState) { 38       if (listener != null) { 39         listener.onScrollStateChanged(view, scrollState); 40       } 41     } 42  43     @Override 44     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 45       if (listener != null) { 46         listener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); 47       } 48       // 刷新 49       refreshHead(firstVisibleItem, false); 50     } 51   }; 52  53   protected void refreshHead(int firstVisibleItem, boolean forceRefresh) { 54     // 防空 55     if (headLayout == null || adapter == null || adapter.getHeadPos() == null 56         || listView.getChildAt(0) == null) { 57       return; 58     } 59  60     // 获取头部位置记录 61     ArrayList<Integer> headPos = adapter.getHeadPos(); 62     // 是否有找到head 63     boolean find = false; 64  65     // 获取head中的位置 66     int prevHeadPos = -1; 67     if (headLayout.getChildCount() > 0 && headLayout.getChildAt(0) != null && 68         headLayout.getChildAt(0).getTag() != null) { 69       prevHeadPos = (int) headLayout.getChildAt(0).getTag(); 70     } 71  72     // 反向遍历头部位置记录 73     for (int i = (headPos.size() - 1); i>=0; i--) { 74       // 如果当前位置大于等于某个头部记录,表示应该使用该头部 75       if (firstVisibleItem >= headPos.get(i)) { 76         // 获取headLayout中视图的pos标签 77  78         // 构造或者从headLayout中获取视图 79         View v; 80         if (prevHeadPos == -1 || prevHeadPos != headPos.get(i) || forceRefresh) { 81           // 无Pos标签或POS标签不配对 82           headLayout.removeAllViews(); 83           v = listView.getAdapter().getView(headPos.get(i), null, null); 84           v.setTag(headPos.get(i)); 85           LayoutParams params = new FrameLayout.LayoutParams(-1, -2); 86           v.setLayoutParams(params); 87           headLayout.addView(v); 88         } else if (i+1 < headPos.size() && firstVisibleItem == headPos.get(i+1) - 1) { 89           // 当前第一个item的top值 90           int top = listView.getChildAt(0).getTop(); 91           // Pos标签配对但,有下一个head,且下一个head的pos为下一个item时 92           v = headLayout.getChildAt(0); 93           // 设置head的Top 94           LayoutParams params = (LayoutParams) v.getLayoutParams(); 95           params.setMargins(0, top, 0, -top); 96           v.setLayoutParams(params); 97         } else { 98           // 修正head top没有回到0的问题 99           v = headLayout.getChildAt(0);100           LayoutParams params = (LayoutParams) v.getLayoutParams();101           if (params.topMargin != 0) {102             params.setMargins(0, 0, 0, 0);103             v.setLayoutParams(params);104           }105         }106         find = true;107         break;108       }109     }110     // 未找到head的情况,清空Head111     if (!find && headLayout != null) {112       headLayout.removeAllViews();113     }114   }115 116   public StickHeaderListView(Context context) {117     super(context);118     this.context = context;119   }120 121   public StickHeaderListView(Context context, AttributeSet attrs) {122     super(context, attrs);123     this.context = context;124   }125 126   public void setBackgroundColor(int color) {127     if (listView != null) {128       listView.setBackgroundColor(color);129     }130   }131 132   public void addFooterView(View v) {133     if (listView != null) {134       listView.addFooterView(v);135     }136   }137 138   public boolean removeFooterView(View v) {139     if (listView != null) {140       return listView.removeFooterView(v);141     }142     return false;143   }144 145   public int getFooterViewsCount() {146     if (listView != null) {147       return listView.getFooterViewsCount();148     }149     return 0;150   }151 152   public void setDividerHeight(int height) {153     if (listView != null) {154       listView.setDividerHeight(height);155     }156   }157 158   public void setCacheColorHint(int color) {159     if (listView != null) {160       listView.setCacheColorHint(color);161     }162   }163 164   public void setSelector(int resID) {165     if (listView != null) {166       listView.setSelector(resID);167     }168   }169 170   public void setAdapter(StickHeaderAdapter adapter) {171     if (adapter instanceof BaseAdapter && listView != null) {172       this.adapter = adapter;173       if (adapter != null && mDataSetObserver != null) {174         try {175           ((BaseAdapter) adapter).unregisterDataSetObserver(mDataSetObserver);176         } catch (Exception e) {}177       }178       listView.setAdapter((ListAdapter) this.adapter);179       ((BaseAdapter) adapter).registerDataSetObserver(mDataSetObserver);180     }181   }182 183   public void setOnScrollListener(OnScrollListener listener) {184     this.listener = listener;185   }186 187   @Override188   protected void onFinishInflate() {189     super.onFinishInflate();190     // 添加列表,属性直接使用父视图191     listView = new ListView(context);192     listView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,193         ViewGroup.LayoutParams.MATCH_PARENT));194     addView(listView);195     // 添加head196     headLayout = new FrameLayout(context);197     headLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,198         ViewGroup.LayoutParams.WRAP_CONTENT));199     addView(headLayout);200     // 添加滚动监听201     listView.setOnScrollListener(scrollListener);202   }203 204   public interface OnScrollListener extends AbsListView.OnScrollListener {}205 206   public interface StickHeaderAdapter {207     public ArrayList<Integer> getHeadPos();208   }209 }

原标题:【原创】StickHeaderListView的简单实现,解决footerView问题

关键词:ie

ie
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。