android之ScrollView里嵌套ListView(轉)


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM