/**
- DemoListView
- @version 1.0
- @author WuXx
- @Time 2014-08-15
- / /
一、实现功能:#
(1)当列数较多,超过一屏时,整体视图支持左右滑动;
(2)当单列数据较长,可以通过拖拽表头改变列宽;
(3)为表格中每一项添加点击事件。
二、效果图:#
<span style="color: #000000;">图片有些小。</span>
三、搭建布局:#
四、主要代码:#
由易到难顺序:MyOnItemClickListener、MyListView、MyAdapter#
(1)MyOnItemClickListener,回调函数机制。由MyAdapter调用。#
**[java]** [view plain](http://blog.csdn.net/hello1234123/article/details/38590073#)[copy](http://blog.csdn.net/hello1234123/article/details/38590073#)[print](http://blog.csdn.net/hello1234123/article/details/38590073#)[?](http://blog.csdn.net/hello1234123/article/details/38590073#)
<div>
</div>
</div>
</div>
- <span style="color: black;"><span style=<span class="string" style="color: blue;">“font-weight: normal;”</span>><span class="keyword" style="color: #006699;">public</span> <span class="keyword" style="color: #006699;">interface</span> MyOnItemClickListener { </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">public</span> <span class="keyword" style="color: #006699;">void</span> OnItemClickListener(View view,<span class="keyword" style="color: #006699;">int</span> line,<span class="keyword" style="color: #006699;">int</span> row,<span class="keyword" style="color: #006699;">long</span> id); </span>
- <span style="color: black;">} </span>
- <span style="color: black;"></span> </span>
(2)MyListView,表头滑动事件,滑动事件会与HorizontalScrollView的滑动冲突,解决方案:在MotionEvent.ACTION_DOWN,设置一下HorizontalScrollView的touch不监听就好了。#
**[java]** [view plain](http://blog.csdn.net/hello1234123/article/details/38590073#)[copy](http://blog.csdn.net/hello1234123/article/details/38590073#)[print](http://blog.csdn.net/hello1234123/article/details/38590073#)[?](http://blog.csdn.net/hello1234123/article/details/38590073#)
<div>
</div>
</div>
</div>
- <span style="color: black;"><span style=<span class="string" style="color: blue;">“font-weight: normal;”</span>><span class="comment" style="color: #008200;">/**</span> </span>
- <span style="color: black;"><span class="comment" style="color: #008200;"> * Set TouchListener on tile ,if ACTION_MOVE is called ,the listView will change its columnWidth</span> </span>
- <span style="color: black;"><span class="comment" style="color: #008200;"> * */</span> </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">private</span> <span class="keyword" style="color: #006699;">void</span> setTitleTouchListener(View v) { </span>
- <span style="color: black;"> <span class="comment" style="color: #008200;">// TODO Auto-generated method stub</span> </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">for</span>(<span class="keyword" style="color: #006699;">int</span> i=<span class="number" style="color: #c00000;"></span>;i<titles.length;i++){ </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">final</span> <span class="keyword" style="color: #006699;">int</span> column = i; </span>
- <span style="color: black;"> v.findViewById(titles[i]).setOnTouchListener(<span class="keyword" style="color: #006699;">new</span> OnTouchListener() { </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">int</span> x = <span class="number" style="color: #c00000;"></span>; </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">int</span> x1 = <span class="number" style="color: #c00000;"></span>; </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">int</span> width = <span class="number" style="color: #c00000;"></span>; </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">boolean</span> isMoved = <span class="keyword" style="color: #006699;">false</span>; </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">int</span> t = <span class="number" style="color: #c00000;">20</span>; </span>
- <span style="color: black;"> <span class="annotation" style="color: #646464;">@SuppressLint</span>(<span class="string" style="color: blue;">“NewApi”</span>)</span> </span>
- <span style="color: black;"> <span style=<span class="string" style="color: blue;">“font-weight: normal;”</span>> <span class="annotation" style="color: #646464;">@Override</span> </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">public</span> <span class="keyword" style="color: #006699;">boolean</span> onTouch(View v, MotionEvent event) { </span>
- <span style="color: black;"> <span class="comment" style="color: #008200;">// TODO Auto-generated method stub</span> </span>
- <span style="color: black;"> <span class="comment" style="color: #008200;">//two teps</span> </span>
- <span style="color: black;"> <span class="comment" style="color: #008200;">// 1.when touch down and move, change the width of head;</span> </span>
- <span style="color: black;"> <span class="comment" style="color: #008200;">// 2.touch up ,change the width of the columns ;</span> </span>
- <span style="color: black;"> </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">if</span> (event.getAction() == MotionEvent.ACTION_DOWN) { </span>
- <span style="color: black;"> x = (<span class="keyword" style="color: #006699;">int</span>) event.getX(); </span>
- <span style="color: black;"> hs.requestDisallowInterceptTouchEvent(<span class="keyword" style="color: #006699;">true</span>); </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">return</span> <span class="keyword" style="color: #006699;">true</span>; </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">if</span> (event.getAction() == MotionEvent.ACTION_MOVE) { </span>
- <span style="color: black;"> x1 = (<span class="keyword" style="color: #006699;">int</span>) event.getX(); </span>
- <span style="color: black;"> width= v.getMeasuredWidth()+(x1-x)+t; </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">if</span>(t!=<span class="number" style="color: #c00000;"></span>) </span>
- <span style="color: black;"> t=<span class="number" style="color: #c00000;"></span>; </span>
- <span style="color: black;"> v.setLayoutParams(<span class="keyword" style="color: #006699;">new</span> LinearLayout.LayoutParams(width,v.getMeasuredHeight())); </span>
- <span style="color: black;"> x = x1; </span>
- <span style="color: black;"> isMoved = <span class="keyword" style="color: #006699;">true</span>; </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">return</span> <span class="keyword" style="color: #006699;">true</span>; </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">if</span>(event.getAction()==MotionEvent.ACTION_UP){ </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">if</span>(isMoved) </span>
- <span style="color: black;"> adapter.setColumnWidth(column, width); </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">return</span> <span class="keyword" style="color: #006699;">true</span>; </span>
- <span style="color: black;"> </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">if</span>(event.getAction()==MotionEvent.ACTION_CANCEL){ </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">if</span>(isMoved) </span>
- <span style="color: black;"> adapter.setColumnWidth(column, width); </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">return</span> <span class="keyword" style="color: #006699;">true</span>; </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">return</span> <span class="keyword" style="color: #006699;">true</span>; </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> }); </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> }</span> </span>
(3)MyAdapter,这个有点小麻烦。参考SimpleAdapter来写的,不过略有不同。与SimpleAdapter重复部分不再赘述。详细内容请下载源代码看吧。#
数据以及点击事件的添加,其实是很简单的。#
**[java]** [view plain](http://blog.csdn.net/hello1234123/article/details/38590073#)[copy](http://blog.csdn.net/hello1234123/article/details/38590073#)[print](http://blog.csdn.net/hello1234123/article/details/38590073#)[?](http://blog.csdn.net/hello1234123/article/details/38590073#)
<div>
</div>
</div>
</div>
- <span style="color: black;"><span class="keyword" style="color: #006699;">private</span> <span class="keyword" style="color: #006699;">void</span> bindView(<span class="keyword" style="color: #006699;">int</span> position, View v) { </span>
- <span style="color: black;"> <span class="comment" style="color: #008200;">// TODO Auto-generated method stub</span> </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">for</span> (<span class="keyword" style="color: #006699;">int</span> i = <span class="number" style="color: #c00000;"></span>; i < mFrom.length; i++) { </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">final</span> <span class="keyword" style="color: #006699;">int</span> line = position; </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">final</span> <span class="keyword" style="color: #006699;">int</span> row = i; </span>
- <span style="color: black;"> TextView txt = (TextView) v.findViewById(mTo[i]); </span>
- <span style="color: black;"> txt.setText((String) mData.get(position).get(mFrom[i])); </span>
- <span style="color: black;"> txt.setOnClickListener(<span class="keyword" style="color: #006699;">new</span> OnClickListener() { </span>
- <span style="color: black;"> <span class="annotation" style="color: #646464;">@Override</span> </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">public</span> <span class="keyword" style="color: #006699;">void</span> onClick(View v) { </span>
- <span style="color: black;"> <span class="comment" style="color: #008200;">// TODO Auto-generated method stub</span> </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">if</span> (MyAdapter.<span class="keyword" style="color: #006699;">this</span>.listener != <span class="keyword" style="color: #006699;">null</span>) </span>
- <span style="color: black;"> MyAdapter.<span class="keyword" style="color: #006699;">this</span>.listener.OnItemClickListener(v, line, </span>
- <span style="color: black;"> row, <span class="number" style="color: #c00000;"></span>); </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> }); </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> } </span>
修改列宽,当MyListView滑动表头时修改表格主体的列宽。#
**[java]** [view plain](http://blog.csdn.net/hello1234123/article/details/38590073#)[copy](http://blog.csdn.net/hello1234123/article/details/38590073#)[print](http://blog.csdn.net/hello1234123/article/details/38590073#)[?](http://blog.csdn.net/hello1234123/article/details/38590073#)
<div>
</div>
</div>
</div>
- <span style="color: black;"><span class="keyword" style="color: #006699;">public</span> <span class="keyword" style="color: #006699;">void</span> setColumnWidth(<span class="keyword" style="color: #006699;">int</span> column, <span class="keyword" style="color: #006699;">int</span> width) { </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">for</span> (<span class="keyword" style="color: #006699;">int</span> i = <span class="number" style="color: #c00000;"></span>; i < viewList.size(); i++) { </span>
- <span style="color: black;"> View v = viewList.get(i); </span>
- <span style="color: black;"> TextView txt = (TextView) v.findViewById(mTo[column]); </span>
- <span style="color: black;"> txt.setLayoutParams(<span class="keyword" style="color: #006699;">new</span> LinearLayout.LayoutParams(width, txt </span>
- <span style="color: black;"> .getHeight())); </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> } </span>
好吧,问题来了。当使用此方法进行显示时,当你滑动表头修改列宽,你再下拉查看未显示的数据,这个时候惊喜来了,空白?嗯是的。发现有一行的部分数据项是空白的,当你继续下拉,你会发现这个空白会循环的出现在你屏幕上,也许你猜到了这其中的原因。我们可以举一个例子,假如你的ListView第一次加载出来,屏幕上显示的item数量为23个,但是,getView调用了24次,当然,我这么说是不负责的,好吧,准确的说是生成了24个View(就是你的item),why 24?因为有一个影藏的。第24个View的产生是因为安卓内部有一个recycler机制,实现了View的循环使用,显而易见,23个是无法实现循环的。这里我借鉴网上的一张图,大家就一目了然了。#
这时,聪明的你发现了,我们没有涉及到如何在getView中找出影藏的View。其实这个问题我也没有特别好的解决方案,目前我采取的方案,可以在把空白问题出现的概率控制在比较小的范围。这种方案是通过5、6次调试通过log日志得出的,有一定的局限性。#
通过getView给出的参数,position、parent以及用来存储视图的ViewList,进行判断影藏的View。代码如下:#
**[java]** [view plain](http://blog.csdn.net/hello1234123/article/details/38590073#)[copy](http://blog.csdn.net/hello1234123/article/details/38590073#)[print](http://blog.csdn.net/hello1234123/article/details/38590073#)[?](http://blog.csdn.net/hello1234123/article/details/38590073#)
<div>
</div>
</div>
</div>
- <span style="color: black;"><span class="keyword" style="color: #006699;">if</span>(lastViewsSize==viewList.size()){ </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">if</span>(position!=<span class="number" style="color: #c00000;"></span>){ </span>
- <span style="color: black;"> <span class="keyword" style="color: #006699;">if</span>(position==parent.getChildCount()&&position==viewList.size()-<span class="number" style="color: #c00000;">1</span>){ </span>
- <span style="color: black;"> setWidth(v); </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> } </span>
- <span style="color: black;"> }<span class="keyword" style="color: #006699;">else</span> { </span>
- <span style="color: black;"> lastViewsSize = viewList.size(); </span>
- <span style="color: black;"> } </span>
大概描述一下:#
首先申明,当ListView在一个屏幕上显示23个时,它并不只是调用24次Adapter的getView,正常情况应该是23(或者说是24,这个值我不能确定)的3、4倍,为什么有这么多呢?其中有一次是用于确定布局的宽度和高度用于draw的,其他的我不清楚。#
但是,可以确定当最后一次调用getView时是用于显示的,我们如何确定这一次呢,通过log日志可以看出,此时viewList.size()已经为常值,所以第一个判断条件便是如此产生的,当然我们需要排除掉position为0的干扰,最后我们找出我们影藏的View,然后setWidth,游戏就这样结束了。我觉得有必要把调试过程中log日志也贴出来:#
源代码:http://download.csdn.net/detail/hello1234123/7765011#
转自:http://blog.csdn.net/hello1234123/article/details/38590073
💬 评论