1. 程式人生 > >android之ScrollView裡巢狀ListView(都可滾動)

android之ScrollView裡巢狀ListView(都可滾動)

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

其實實現原理很簡單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
    }

有些裝置上,依然不響應。則修改ScrollView。

public class ScrollScrollView extends ScrollView {


    GetListViewPos getPos;
    public ScrollScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if(getPos != null){
                int scrollY = getScrollY();
                int listTop = getPos.getTop() - scrollY;
                int listBtm = getPos.getBottom() - scrollY;
                int listLeft = getPos.getLeft();
                int listR = getPos.getRight();
                int y = (int) ev.getY();
                int x = (int) ev.getX();
                if(x > listLeft && x < listR && y > listTop && y < listBtm){
                    requestDisallowInterceptTouchEvent(true);
                    return false;
                }
            }
        case MotionEvent.ACTION_MOVE:
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            break;
        default:
            break;
        }
        boolean retn = super.onInterceptTouchEvent(ev);
        return retn;
    }
    
    public static interface GetListViewPos{
        int getTop();
        int getBottom();
        int getLeft();
        int getRight();
    }


    public void setGetListViewPos(GetListViewPos getListViewPos) {
        getPos = getListViewPos;
    }
}