2017-09-10 5 views
1

J'ai un ViewPager qui réside à l'intérieur d'une disposition linéaire parente et sous le ViewPager il y a quelques boutons. Le ViewPager fonctionnait bien jusqu'à récemment, j'ai changé le parent de LinearLayout à un ScrollView. Maintenant, le ViewPager a disparu. Merci de ne pas le marquer comme spam ou duplicata.Impossible de placer ViewPager à l'intérieur d'un ScrollVIew/NestedScrollView

De plus, il y a des tonnes d'applications sur Playstore utilisant actuellement ceci. Voir cette application - link

Ce que j'essayées:

  1. setFillViewport (true) - Cela ne fonctionne pas pour moi.
  2. Set layout_height à 0DP
  3. Utilisez un CustomScrollView

Tout cela ne me permet pas. Je courais l'application sur Android M.

Ceci est mon 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> 

Question:

Comment puis-je y parvenir? Aussi, existe-t-il une façon officielle de le faire?

+0

Mettez ur scrollview imbriquées à l'intérieur une mise en page parent ex: coordinatorLayout – MrCurious

+0

Cela n'aide pas non plus – Rohn

+0

post full xml .. – phpdroid

Répondre

0

Je résolu la question en fixant la hauteur de mon ViewPager comme:

<?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> 
0

Mieux utiliser un recyclerView et ajouter Viewpager en tant qu'enfant à l'intérieur de l'adaptateur. Vous devez intercepter la touche de recyclage pour donner le parchemin à 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; 
    } 
} 

l'intérieur de l'adaptateur pour RecyclerView vous pouvez ajouter ViewPager comme ceci:

@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; 
    } 
+0

Merci Harsh pour épargner du temps pour la réponse. Peut-être que je peux utiliser une vue Recycler et faire le travail mais il y a une différence conceptuelle entre RecyclerView et ScrollView. Je veux savoir s'il existe un moyen d'utiliser ScrollView et ViewPager ensemble? – Rohn

+0

Oui, vous pouvez utiliser le scrollview de la même manière que vous devez gérer le toucher pour les deux. – Harsh