/**

  • 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;">&#8220;font-weight: normal;&#8221;</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;">&#8220;font-weight: normal;&#8221;</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;">&#8220;NewApi&#8221;</span>)</span>  </span>
  
  - <span style="color: black;">    <span style=<span class="string" style="color: blue;">&#8220;font-weight: normal;&#8221;</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
&nbsp;





转自:http://blog.csdn.net/hello1234123/article/details/38590073

💬 评论