项目中要实现一个列表,表头和内容可以水平滑动,列表的第一列固定,可以上下滑动不能左右滑动。
大概实现思路,表头和内容使用同一个layout文件,确保显示内容的宽度一致,item布局中需要的MyHScrollView继承HorizontalScrollView,让它可以水平滑动。
事件处理,我们要知道的是,viewgroup的事件处理流程,先是对viewgroup的dispatchTouchEvent事件进行分发,调用viewgroup的onInterceptTouchEvent方法,如果onInterceptTouchEvent返回true,则viewgroup自身处理,不会下发给子view,如果onInterceptTouchEvent返回false,且子view可以点击,那子view去处理,viewgroup不会再ontouch函数执行。
要做到第一列固定其实还好,在listview的item中,第一个view单独列出就好,水平滑动的时候,让所有的MyHScrollView跟随你点击的那一行内容移动。这里代码采用了观察者模式进行解耦,简洁易懂。(这里简单记录下一个和生产者消费者模式的区别,生产者模式是生产一个消费一个,同样都有一个list进行维护,但这个list是不断增加减少的过程,而观察者主要是通知的过程,一个消息过来后,所有的list都去通知到。)
接下来有个问题在于内容左右滑动的时候,会触发listview的上下滑动,内容的滑动就不是我们想要的了。修改如下:
根据事件分发机制,我们知道,先是触发listview的dispatchTouchevent事件,再执行到listview的onTouch事件,如果onTouch事件返回为true,则listview不能进行上下滑动了。因此增加以下代码进行控制
class ListViewAndHeadViewTouchLinstener implements View.OnTouchListener {
@Override
public boolean onTouch(View arg0, MotionEvent event) {
boolean result = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
m_posdownX = (int)event.getX();
m_posdownY = (int)event.getY();
result = true;
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
if(Math.abs(event.getX()-m_posdownX) > Math.abs(event.getY()-m_posdownY)){
result = true;
}else{
result = false;
}
break;
default:
break;
}
if(result){
headSrcrollView.onTouchEvent(event);
}
return result;
}
}
最后附上项目
下载链接
http://download.youkuaiyun.com/detail/ahjxly/9598110