2016-04-19 1 views
2

et merci de votre visite.Android ViewPager avec PageTransformer et SceneTransition

J'ai été confronté à un comportement étrange en utilisant la combinaison des deux PageTransformer et TransitionManager.

La hiérarchie que j'utilise est assez facile: A viewPager avec chaque page étant fragment. Le fragment a deux dispositions différentes, changeant avec le TransitionManager.go().

La question: Si je suffit de faire défiler la viewPager, tout va bien, et mon pageTransformer applique les bonnes valeurs, créant l'effet de parallaxe désiré. Si je clique juste en arrière pour changer les scènes à l'intérieur d'une page, j'obtiens aussi la sortie désirée.

Cependant, chaque fois que j'utilise le TransitionManager.go() (disons deux fois, pour revenir à la première mise en page) et que je commence à faire défiler mon viewPager, l'effet de parallaxe ne se produit plus.

Ma question: Y at-il problème connu que je ne l'ai pas pu trouver avec l'aide à la fois un PageTransformer et TransitionManager en même temps?

Mon code:

Fragment1.java

public class Fragment1 extends Fragment { 
private Scene      mStartScene; 
private Scene      mInfoScene; 
private Transition     mTransition; 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.view_pager_item_default, container, false); 

    RelativeLayout rootLayout = (RelativeLayout) v.findViewById(R.id.p1); 

    mTransition = new ChangeBounds(); 
    mTransition.setDuration(400); 

    mStartScene = Scene.getSceneForLayout(rootLayout, R.layout.view_pager_item_default, getContext()); 
    mInfoScene = Scene.getSceneForLayout(rootLayout, R.layout.view_pager_item_details, getContext()); 

    return (v); 
} 

    public void changeScene(View v) { 
    Scene tmp = mInfoScene; 
    mInfoScene = mStartScene; 
    mStartScene = tmp; 
    TransitionManager.go(mStartScene, mTransition); 
    } 
} 

view_pager_item_default.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/p1" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 
<TextView 
    android:id="@+id/textView" 
    android:elevation="20dp" 
    android:text="Item 1" 
    android:onClick="changeScene" 
    android:layout_marginLeft="20dp" 
    android:layout_marginRight="20dp" 
    android:layout_marginBottom="60dp" 
    android:layout_width="match_parent" 
    android:layout_alignParentBottom="true" 
    android:padding="20dp" 
    android:layout_height="wrap_content" 
    android:background="@drawable/white_shape" 
    android:textSize="40sp" 
    android:gravity="center" 
    android:textColor="#000000"/> 
<ImageView 
    android:id="@+id/imageView" 
    android:elevation="19dp" 
    android:scaleType="centerCrop" 
    android:layout_marginBottom="-10dp" 
    android:layout_centerHorizontal="true" 
    android:src="@mipmap/big_image" 
    android:background="@android:color/transparent" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 
</RelativeLayout> 

view_pager_item_details.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/p1" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 
<TextView 
    android:id="@+id/textView" 
    android:elevation="20dp" 
    android:text="Item 1 description" 
    android:onClick="changeScene" 
    android:layout_marginTop="150dp" 
    android:layout_marginLeft="20dp" 
    android:layout_marginRight="20dp" 
    android:layout_marginBottom="20dp" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@drawable/white_shape" 
    android:clickable="true" 
    android:textSize="30sp" 
    android:gravity="center" 
    android:textColor="#000000"/> 
<ImageView 
    android:id="@+id/imageView" 
    android:elevation="21dp" 
    android:layout_marginTop="50dp" 
    android:layout_centerHorizontal="true" 
    android:src="@mipmap/small_image" 
    android:background="@android:color/transparent" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" /> 
</RelativeLayout> 

Mon adaptateur est assez simple:

public class MyPagerAdapter extends FragmentPagerAdapter { 
    private final List     fragments; 

    public MyPagerAdapter(FragmentManager fm, List fragments) { 
    super(fm); 
    this.fragments = fragments; 
    } 

    @Override 
    public Fragment getItem(int position) { 
    return (Fragment) this.fragments.get(position); 
    } 

    @Override 
    public int getCount() { 
    return this.fragments.size(); 
    } 
} 

Alors est mon PageTransformer qui se déplace chaque enfant de la vue indépendamment

public class MyPagerTransformer implements ViewPager.PageTransformer { 
    private float       mParallaxCoeff; 
    private float       mDistanceCoeff; 

    public MyPagerTransformer(float parallax, float distance) { 
    mParallaxCoeff = parallax; 
    mDistanceCoeff = distance; 
    } 

    @Override 
    public void transformPage(View page, float position) { 
    float coefficient = page.getWidth() * mParallaxCoeff; 
    ViewGroup vG = (ViewGroup) page; 
    for (int i = vG.getChildCount() - 1; i >= 0; --i) { 
     View v = vG.getChildAt(i); 
     if (v != null) { 
      v.setTranslationX(coefficient * (position * position * position)); 
     } 
     coefficient *= mDistanceCoeff; 
    } 
    } 
} 

Et enfin mon activité:

public class MainActivity extends AppCompatActivity { 
    private Fragment1    mFrag1; 
    private Fragment1    mFrag2; 
    private Fragment1    mFrag3; 

    private ViewPager    mViewPager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.content_main); 
    mViewPager = (ViewPager) findViewById(R.id.main_view_pager); 

    CirclePageIndicator indicator = (CirclePageIndicator) findViewById(R.id.indicator); 

    if (mViewPager != null) { 
     mViewPager.setPageTransformer(true, new MyPagerTransformer(8.0f, 8.0f)); 

     //vp.addOnPageChangeListener(listener); 
     List<Fragment> fragments = new ArrayList<>(); 

     mFrag1 = new Fragment1(); 
     mFrag2 = new Fragment1(); 
     mFrag3 = new Fragment1(); 
     fragments.add(mFrag1); 
     fragments.add(mFrag2); 
     fragments.add(mFrag3); 

     PagerAdapter realViewPagerAdapter = new MyPagerAdapter(super.getSupportFragmentManager(), fragments); 

     mViewPager.setAdapter(realViewPagerAdapter); 
     indicator.setViewPager(mViewPager); 
    } 
    } 

    public void changeScene(View v) { 
    switch (mViewPager.getCurrentItem()) { 
     case 0: 
      mFrag1.changeScene(v); 
      break; 
     case 1: 
      mFrag2.changeScene(v); 
      break; 
     case 2: 
      mFrag3.changeScene(v); 
      break; 
     default: 
      break; 
    } 
    } 
} 

Enfin, voici un gif montrant ce qui se passe. Comme vous pouvez le voir, au début "Item 1" a l'effet de parallaxe. Après avoir basculé les scènes d'avant en arrière, le PageTransformer ne s'appliquera plus.

Merci d'avance!

Issue in action

Répondre

0

Je répondrai à ma question qui que ce soit de cas bousculait le même problème que moi. Le problème venait du rootLayout que j'utilisais dans le fragment n'étant pas "le bon", donc le TransitionManager ajoutait une couche supplémentaire quand on revenait à la première scène.

Voici ce que j'ai changé:

Fragment1.java

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    //view_pager_root.xml is a simple empty FrameLayout 
    View v = inflater.inflate(R.layout.view_pager_root, container, false); 

    RelativeLayout rootLayout = (RelativeLayout) v.findViewById(R.id.p1); 

    mTransition = new ChangeBounds(); 
    mTransition.setDuration(400); 

    mStartScene = Scene.getSceneForLayout(rootLayout, R.layout.view_pager_item_default, getContext()); 
    mInfoScene = Scene.getSceneForLayout(rootLayout, R.layout.view_pager_item_details, getContext()); 

    return (v); 
} 

Depuis que j'ajouté une autre couche dans ma hiérarchie, je devais aussi changer légèrement mon PageTransformer:

@Override 
public void transformPage(View page, float position) { 
    float coefficient = page.getWidth() * mParallaxCoeff; 
    //vG is the FrameLayout 
    ViewGroup vG = (ViewGroup) page; 
    if (vG.getChildAt(0) instanceof ViewGroup) { 
     //vG is now the RelativeLayout from the scene 
     vG = (ViewGroup) vG.getChildAt(0); 
     for (int i = vG.getChildCount() - 1; i >= 0; --i) { 
      View v = vG.getChildAt(i); 
      if (v != null) { 
       v.setTranslationX(coefficient * (position * position * position)); 
      } 
      coefficient *= mDistanceCoeff; 
     } 
    } 
}