ScrollView中嵌套ScrollView或ListView而且内部ScrollView或ListView也可滑动

1.ScrollView中嵌套ScrollView而且内部ScrollView也可滑动

(1)ScrollView继承类

public class InnerScrollView extends ScrollView {

    Handler handler;

    public ScrollView parentScrollView;

    public InnerScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        handler = new Handler();

    }

    private int lastScrollDelta = 0;

    public void resume() {
        overScrollBy(0, -lastScrollDelta, 0, getScrollY(), 0, getScrollRange(), 0, 0, true);
        lastScrollDelta = 0;
    }

    int mTop = 10;

    /**
     * 将targetView滚到最顶端
     */
    public void scrollTo(final View targetView) {

        handler.postDelayed(new Runnable() {

            @Override
            public void run() {
                int oldScrollY = getScrollY();
                int top = targetView.getTop() - mTop;
                final int delatY = top - oldScrollY;
                lastScrollDelta = delatY;
                smoothScrollTo(0, top);
            }
        }, 50);

    }

    private int getScrollRange() {
        int scrollRange = 0;
        if (getChildCount() > 0) {
            View child = getChildAt(0);
            scrollRange = Math.max(0, child.getHeight() - (getHeight()));
        }
        return scrollRange;
    }

    int currentY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (parentScrollView == null) {
            return super.onInterceptTouchEvent(ev);
        } else {
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                // 将父scrollview的滚动事件拦截
                currentY = (int)ev.getY();
                setParentScrollAble(false);
                return super.onInterceptTouchEvent(ev);
            } else if (ev.getAction() == MotionEvent.ACTION_UP) {
                // 把滚动事件恢复给父Scrollview
                setParentScrollAble(true);
            } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
            }
        }
        return super.onInterceptTouchEvent(ev);

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        View child = getChildAt(0);
        if (parentScrollView != null) {
            if (ev.getAction() == MotionEvent.ACTION_MOVE) {
                int height = child.getMeasuredHeight();
                height = height - getMeasuredHeight();

                // System.out.println("height=" + height);
                int scrollY = getScrollY();
                // System.out.println("scrollY" + scrollY);
                int y = (int)ev.getY();

                // 手指向下滑动
                if (currentY < y) {
                    if (scrollY <= 0) {
                        // 假设向下滑动到头。就把滚动交给父Scrollview
                        setParentScrollAble(true);
                        return false;
                    } else {
                        setParentScrollAble(false);

                    }
                } else if (currentY > y) {
                    if (scrollY >= height) {
                        // 假设向上滑动到头,就把滚动交给父Scrollview
                        setParentScrollAble(true);
                        return false;
                    } else {
                        setParentScrollAble(false);

                    }

                }
                currentY = y;
            }
        }

        return super.onTouchEvent(ev);
    }

    /**
     * 是否把滚动事件交给父scrollview
     * 
     * @param flag
     */
    private void setParentScrollAble(boolean flag) {

        parentScrollView.requestDisallowInterceptTouchEvent(!flag);
    }
}

(2)ScrollView使用Activity

public class ScrollViewActivity extends Activity {

    ScrollView scrollView1;

    InnerScrollView innerScrollView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        scrollView1 = (ScrollView)findViewById(R.id.scroll_1);
        innerScrollView = (InnerScrollView)findViewById(R.id.scroll_2);
        innerScrollView.parentScrollView = scrollView1;
        final Button button = (Button)innerScrollView.findViewById(R.id.scroll_button2);
        final View content = findViewById(R.id.scroll_content);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                if (content.getVisibility() == View.VISIBLE) {
                    innerScrollView.resume();
                    content.setVisibility(View.GONE);
                } else {
                    innerScrollView.scrollTo(v);
                    content.setVisibility(View.VISIBLE);
                }
            }
        });

    }
}

2.ScrollView中嵌套ListView而且内部ListView也可滑动

(1)ScrollView继承类

public class InnerListView extends ListView {

    ScrollView parentScrollView;

    public ScrollView getParentScrollView() {
        return parentScrollView;
    }

    public void setParentScrollView(ScrollView parentScrollView) {
        this.parentScrollView = parentScrollView;
    }

    private int maxHeight;

    public int getMaxHeight() {
        return maxHeight;
    }

    public void setMaxHeight(int maxHeight) {
        this.maxHeight = maxHeight;
    }

    public InnerListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @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));
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:

                setParentScrollAble(false);
            case MotionEvent.ACTION_MOVE:

                break;
            case MotionEvent.ACTION_UP:

            case MotionEvent.ACTION_CANCEL:
                setParentScrollAble(true);
                break;
            default:
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    /**
     * @param flag
     */
    private void setParentScrollAble(boolean flag) {
        parentScrollView.requestDisallowInterceptTouchEvent(!flag);
    }

}

(2)ScrollView有用Activity

public class ListViewActivity extends Activity {

    ScrollView scrollView;

    InnerListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_view_test);
        listView = (InnerListView)findViewById(R.id.list);
        scrollView = (ScrollView)findViewById(R.id.scroll_view);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.select_dialog_singlechoice);
        for (int i = 0; i < 100; i++) {
            adapter.add(String.valueOf(i));
        }
        listView.setAdapter(adapter);
        listView.setCacheColorHint(0x00000000);
        listView.setBackgroundDrawable(null);
        listView.setBackgroundColor(Color.WHITE);
        listView.setParentScrollView(scrollView);
        listView.setMaxHeight(400);

    }
}

源代码地址:http://download.csdn.net/detail/pcaxb/8981295

posted @ 2017-05-25 16:13  jhcelue  阅读(162)  评论(0编辑  收藏  举报