android之ScrollView里嵌套ListView(转)

本文详细介绍了如何解决ScrollView嵌套ListView时出现的滚动冲突问题。通过重写ListView的onInterceptTouchEvent方法,并使用requestDisallowInterceptTouchEvent来控制外部ScrollView何时放弃触摸事件,从而实现了内外层均可滚动的效果。
摘要由CSDN通过智能技术生成

Method1

MaxItemListview extends listview

限制listview显示的item数量

private void initView() {
    ListAdapter listAdapter = this.getAdapter();
    if (listAdapter == null) {
        return;
    }
    int dataCount = listAdapter.getCount();
    int totalHeight = 0;
    int itemHeight = 0;
    if (dataCount > 0) {
        View listItem = listAdapter.getView(0, null, this);
        listItem.measure(0, 0);
        itemHeight = listItem.getMeasuredHeight();
    }
    if (dataCount <= MAX_NUM) {
        for (int i = 0; i < dataCount; i++) {
            totalHeight += itemHeight;
        }
    } else {
        totalHeight = MAX_NUM * itemHeight;
    }
    ViewGroup.LayoutParams params = this.getLayoutParams();
    params.height = totalHeight;
    this.setLayoutParams(params);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    initView();
}<strong>
</strong>


Method2

hi,大家好,研究完ScrollView嵌套ScrollView之后,本人突然又想研究ScrollView里嵌套ListView了。
如果还不知道ScrollView嵌套ScrollView是怎么实现的可以参考http://www.eoeandroid.com/thread-240709-1-1.html
在上篇文章当中其实我没有怎么把原理讲清楚,只是上了原代码,而其实ScrollView里套ScrollView和ScrollView里套ListView是同一个道理的。


按常理,ScrollView套ListView会存在两个问题:

1.里面的listView高度无法算出来,通常只能显示listview的其中一行
2.listview不能滚动

在解决问题一的时候,我在网上找了一大堆资料,怎么怎么让listview显示完整,终于被我找到一个帖子,能解决这个问题
http://blog.csdn.net/hitlion2008/article/details/6737459 
(同时我不小心搜到了我的"ScrollView嵌套ScrollView"贴子满天飞...在这里我拜托大家,转贴注明出处啊亲。。。。。)。
按照这个贴子我试了一下,虽然listview的高度出来了,但是存在两个问题:
a.还是只支持ScrollView滚动,listView不会滚动,因为listView的高度已经达到最大,它不需要滚动。
b.listview的优点就是能够复用listItem,如果把listView撑到最大,等于是没有复用listItem,这跟没用listView一样,省不了ui资源,那我还不如直接用linearlayout呢

要怎么才能支持外面的ScrollView和里面的ListView都能滚动呢?

想过很多办法,最终我还是把ScrollView套ScrollView的实现原理搬过来试试看,结果成功了。。。。

其实实现原理很简单ScrollView有一个方法requestDisallowInterceptTouchEvent(boolean);
这个方法是设置是否交出ontouch权限的,如果让外层的scrollview.requestDisallowInterceptTouchEvent(false);那么外层的onTouch权限会失去,这样里面的listview就能
拿到ontouch权限了,listView也就能滚了。
问题是:权限只有一个,要支持两个view都能滚动。这个就有点难实现了吧..

其实这个一点也不难,当手指触到listview的时候,让外面的scrollview交出权限,当手指松开后,外面的scrollview重新获得权限。这样ok了。

且看代码实现:
重写一个InnerListView extends ListView

InnerListView.java

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch 
(ev.getAction()) {
            case  MotionEvent.ACTION_DOWN:
                
setParentScrollAble(false);//当手指触到listview的时候,让父ScrollView交出ontouch权限,也就是让父scrollview停住不能滚动

                LogManager.d("onInterceptTouchEvent 
down");
            case MotionEvent.ACTION_MOVE:
                
LogManager.d("onInterceptTouchEvent move");
                break;
        
    case MotionEvent.ACTION_UP:
                
LogManager.d("onInterceptTouchEvent up");
            case  MotionEvent.ACTION_CANCEL:
                
LogManager.d("onInterceptTouchEvent cancel");
               
 setParentScrollAble(true);//当手指松开时,让父ScrollView重新拿到onTouch权限

        
        break;
            default:
                break;
     
   }
        return super.onInterceptTouchEvent(ev);
    
}


  /**
     * 是否把滚动事件交给父scrollview
     * 
     * @param 
flag
     */
    private void setParentScrollAble(boolean flag) {
     
  parentScrollView.requestDisallowInterceptTouchEvent(!flag);//这里的parentScrollView就是listview外面的那个scrollview
  
  
}

在这里我要提出的是,listview能滚动的前提是:当listview本身的高度小于listview里的子view。

如果在xml里让listview的高度为wrap_content,可能会出现问题,如:ListView的高度会变成跟子view 
的高度一样。

这里最好是让listView的高度固定,平时我们写listView布局的时候也是给一个固定值。如fill_parent或100dip

我写了一个参数叫maxHeight.设置listview的最大高度。是为了确保ListView的高度固定。

  
 private int maxHeight;
    public int getMaxHeight() {
        return 
maxHeight;
    }
    public void setMaxHeight(int maxHeight) {
     
   this.maxHeight = maxHeight;
    }
@Override
    protected void 
onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO 
Auto-generated method stub
        if (maxHeight > -1) {
           
 heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, 
MeasureSpec.AT_MOST);
        }
        super.onMeasure(widthMeasureSpec, 
heightMeasureSpec);
        System.out.println(getChildAt(0));
    }

 

转载于 :http://www.eoeandroid.com/thread-246995-1-1.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值