android 中 ScrollView裡嵌套ListView

來源:互聯網
上載者:User

研究完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));    }

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.