无法将ViewPager放在ScrollVIew / NestedScrollView

时间:2017-09-10 06:46:58

标签: android android-layout android-viewpager scrollview

我有一个ViewPager,它位于父线性布局中,而在ViewPager下面有一些按钮。 ViewPager工作得很好直到最近我将父级从LinearLayout更改为ScrollView。现在ViewPager消失了。请勿将其标记为垃圾邮件或重复邮件。

此外,Playstore上有大量应用程序正在使用此功能。查看此应用 - link

我尝试过的事情:

  1. setFillViewport(true) - 这对我没用。
  2. 将layout_height设置为0dp
  3. 使用CustomScrollView
  4. 所有这些对我没有帮助。我在Android M上运行应用程序。

    这是我的layout.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:fillViewport="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    tools:context=".activities.HomeActivity">
    
    <LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:onClick="pagerClick"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_gravity="top"
    android:layout_weight="1"
    android:overScrollMode="never"/>
    
    <RelativeLayout
    android:layout_weight="0.8"
    android:layout_marginTop="30dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    .....two buttons
    </RelativeLayout>
    
    </LinearLayout>
    
    </android.support.v4.widget.NestedScrollView>
    

    问题:

    我怎样才能做到这一点?还有,有官方的方式吗?

2 个答案:

答案 0 :(得分:0)

最好使用recyclerView并将Viewpager作为其子项添加到适配器中。您需要拦截recyclerview的触摸,以将滚动条提供给ViewPager。

public class TouchInterceptRecyclerView extends RecyclerView {

    private boolean interceptTouch = true;
    private static final int MIN_DISTANCE = 200;
    private float downX = 0, downY = 0, moveX = 0, moveY = 0, upX = 0, upY;

    public TouchInterceptRecyclerView(Context context) {
        super(context);
    }

    public TouchInterceptRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (getRvTop() == 0) {
            onTouchEvent(ev);
        }
        return interceptTouch;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                moveX = event.getX();
                moveY = event.getY();
                break;
            case MotionEvent.ACTION_UP:
                upX = event.getX();
                upY = event.getY();
                break;
        }
        float deltaX = upX - downX;

        if (getViewTop() == 0 && moveY > downY && Math.abs(moveY - downY) > MIN_DISTANCE) {  // moving down
            interceptTouch = true;
        }else if (Math.abs(deltaX) > MIN_DISTANCE) {
            if (upX > downX) {    // Left to Right swipe action
                interceptTouch = false;
            }else {    // Right to left swipe action
                interceptTouch = false;
            }
        } else {  // screen tap
            interceptTouch = false;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return super.dispatchTouchEvent(ev);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
    }

    @Override
    public void onScrolled(int dx, int dy) {
        if (getViewTop() <= 0) {
            interceptTouch = false;            // dispatch the touch to child when reached top
        } else {
            interceptTouch = true;           // do not dispatch the touch event
        }
        super.onScrolled(dx, dy);
    }

    public int getViewTop() {
        int top = 0;
        View v = this.getChildAt(1);
        if (v == null) {
            v = this.getChildAt(0);
        }
        if (v != null && v instanceof LinearLayout) {
            top = v.getTop();
        }
        return top;
    }

    public int getRvTop() {
        int top = -1;
        View v = this.getChildAt(1);
        if (v == null) {
            v = this.getChildAt(0);
        }
        if (v != null && v instanceof LinearLayout) {

            ViewPager vp = (ViewPager) v.findViewById(R.id.single_pager);
            if (vp != null) {
                int currentPos = vp.getCurrentItem();
                RecyclerView rv = (RecyclerView) vp.findViewWithTag("recyclerview" + currentPos);
                if (rv != null) {
                    View v1 = rv.getChildAt(0);
                    if (v1 != null && v1 instanceof CardView) {
                        top = v1.getTop() - ResourceUtils.getDimensionPixelOffset(R.dimen.padding_20);   // deducting 20 as we have give top margin as 20 to the top layout
                    }
                }
            }
        }
        return top;
    }
}

在RecyclerView的适配器中,您可以像这样添加ViewPager:

@Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder viewHolder = null;
        View view;
        switch (viewType) {
            case TYPE_VIEW_PAGER:
                view = LayoutInflater.from(context).inflate(R.layout.pager, parent, false);
                viewHolder = new ViewPagerAdapter(context, view);
                break;
        }
        return viewHolder;
    }

答案 1 :(得分:0)

我通过修改ViewPager的高度解决了这个问题,如:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fillViewport="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
tools:context=".activities.HomeActivity">

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:onClick="pagerClick"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="top"/>

...

</LinearLayout>

</android.support.v4.widget.NestedScrollView>