1、前言: 前几天用了GitHub上se.emilsjolander.stickylistheaders这个组件,然后发现这个组件的listview不能添加footerView,加了footer后,滑倒footer的时候head会消失,与我项目中的需求不符。于是就自己写了一个 ...
1、前言:
前几天用了GitHub上se.emilsjolander.stickylistheaders这个组件,然后发现这个组件的listview不能添加footerView,加了footer后,滑倒footer的时候head会消失,与我项目中的需求不符。
于是就自己写了一个StickHeaderListView,实现比较简单,做法和stickylistheaders基本相同只是没有封装那么多功能,可以添加footer但不能添加header,有需要的同学可以拿去改良后用。
另外由于是临时写的一个组件,代码没做什么优化,如果有想法可以提点意见,谢谢!
2、示例效果:
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
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。