【问题标题】:ViewPager in ScrollView won't scroll verticallyScrollView 中的 ViewPager 不会垂直滚动
【发布时间】:2012-06-02 20:01:29
【问题描述】:

我有一个 布局,它在自定义 ScrollView 内有一个 ViewPager,并且 ViewPager 不会垂直滚动。自定义 ScrollView 用于修复可怕的选项卡滑动 ScrollView。

是的,有足够的内容可以滚动,我尝试过使用和不使用底部按钮。

我正在使用具有 3 个选项卡的 ActionBar,并且当前代码允许向左/向右滑动就好了。

我的目标是为几个操作项(例如保存和取消)设置底部栏,并且 ActionBar 和底部按钮之间的部分是垂直滚动的 ViewPager。

我尝试了太多组合,现在将这封情书寄给你。有任何想法吗?感谢您提供任何帮助,如果需要,请随时询问更多详细信息。

ma​​in.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/footer"
        style="@android:style/Holo.ButtonBar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/saveButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Save" />

        <Button
            android:id="@+id/cancelButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Cancel" />
    </LinearLayout>

    <com.blah.hootiehoo.ViewPagerCompatScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@id/footer"
        android:fillViewport="true" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical"
            android:scrollbarAlwaysDrawVerticalTrack="true"
            android:scrollbars="vertical" >

            <android.support.v4.view.ViewPager
                android:id="@+id/pager"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_weight="1"
                android:scrollbarAlwaysDrawVerticalTrack="true"
                android:scrollbars="vertical" >
            </android.support.v4.view.ViewPager>
        </LinearLayout>
    </com.blah.hootiehoo.ViewPagerCompatScrollView>

</RelativeLayout>

MainActivity.java

ViewPager mViewPager;
TabsAdapter mTabsAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);
    mViewPager = (ViewPager)findViewById(R.id.pager);

    // setup action bar for tabs
    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setDisplayShowTitleEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(true);   

    mTabsAdapter = new TabsAdapter(this, mViewPager);

    Tab tab = actionBar.newTab();
    // tab setup
    mTabsAdapter.addTab(/*** stuff ***/);

    // add 2 more tabs, etc
}

ViewPagerCompatScrollView.java Got from here, at bottom

public class ViewPagerCompatScrollView extends ScrollView {
    private float xDistance, yDistance, lastX, lastY;

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                xDistance = yDistance = 0f;
                lastX = ev.getX();
                lastY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                final float curX = ev.getX();
                final float curY = ev.getY();
                xDistance += Math.abs(curX - lastX);
                yDistance += Math.abs(curY - lastY);
                lastX = curX;
                lastY = curY;
                if(xDistance > yDistance)
                    return false;
        }

        return super.onInterceptTouchEvent(ev);
    }
}

【问题讨论】:

  • 是否可以交换ScrollView 和ViewPager?根据经验,我知道 ScrollView inside 和 ViewPager 可以正常工作。所以基本上不是用ScrollView包装ViewPager,而是给每个“页面”一个ScrollView作为root。
  • 一旦我明白了该做什么,它就完美地工作了。这也消除了对自定义 ScrollView 的需求。看来这是个相当秘密的事情。如果您想为此获得荣誉,请尽快回复。
  • 太好了,很高兴听到您解决了您的问题。冒昧地将评论添加为下面的答案。干杯。

标签: android android-layout


【解决方案1】:

根据之前的评论:

是否可以交换ScrollView 和ViewPager?根据经验,我知道ViewPager 中的ScrollView 可以正常工作。所以基本上不是用ScrollView 包装ViewPager,而是给每个“页面”一个ScrollView 作为根。

很高兴听到这对你有用。

【讨论】:

  • 我已经完全按照您的建议实现了我的应用程序。不幸的是,ViewPager 中的垂直 ScrollViews 不会进行平滑滚动(即通过 smoothScrollTo 方法)。它们只是“跳”到最后的 y 位置,因此用户不会意识到发生了滚动。有什么建议么?谢谢!
【解决方案2】:

MH。答案应该有效。

您的代码中的问题是ViewPager 将具有与ScrollView 相同的height,因此它不会滚动。 ViewPager 中的每个子 View 也将获得与 ViewPager 相同的 height。

尝试手动设置ViewPager 的height eks android:layout_height="900dp",它会滚动得很好...

但你真的应该使用 MH.'s answer :)

【讨论】:

  • 感谢您花时间查看我的问题。有一个 +1!
【解决方案3】:

我遇到了类似的问题。这是我解决它的方法。

imageGrid.setOnTouchListener(new View.OnTouchListener() {

        int dragthreshold = 30;
        int downX;
        int downY;

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = (int) event.getRawX();
                downY = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                int distanceX = Math.abs((int) event.getRawX() - downX);
                int distanceY = Math.abs((int) event.getRawY() - downY);

                if (distanceY > distanceX && distanceY > dragthreshold) {
                    imageGrid.getParent().requestDisallowInterceptTouchEvent(false);
                    parentScrollView.getParent().requestDisallowInterceptTouchEvent(true);
                } else if (distanceX > distanceY && distanceX > dragthreshold) {
                    imageGrid.getParent().requestDisallowInterceptTouchEvent(true);
                    parentScrollView.getParent().requestDisallowInterceptTouchEvent(false);
                }
                break;
            case MotionEvent.ACTION_UP:
                parentScrollView.getParent().requestDisallowInterceptTouchEvent(false);
                imageGrid.getParent().requestDisallowInterceptTouchEvent(false);
                break;
            }
            return false;
        }
    });

值得一试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多