2016-04-19 12 views
2

und danke für Ihren Besuch.Android ViewPager mit PageTransformer und SceneTransition

Ich habe ein seltsames Verhalten mit der Kombination von PageTransformer und TransitionManager konfrontiert.

Die Hierarchie, die ich verwende, ist ziemlich einfach: A viewPager mit jeder Seite ist eine fragment. Das Fragment hat zwei verschiedene Layouts, die sich mit der TransitionManager.go() ändern.

Das Problem: Wenn ich die viewPager nur blättern, alles ist in Ordnung, und mein pageTransformer gilt die richtigen Werte, den gewünschten Parallaxe-Effekt. Wenn ich nur vor und zurück klicke, um Szenen innerhalb einer Seite zu wechseln, bekomme ich auch die gewünschte Ausgabe.

Allerdings, wenn ich die TransitionManager.go() (sagen wir zweimal, um zurück zum ersten Layout zu gehen) und dann scrollen durch meine ViewPager, der Parallax-Effekt nicht mehr auftreten.

Meine Frage: Gibt es ein bekanntes Problem, das ich nicht in der Lage gewesen, mit der Verwendung von sowohl ein PageTransformer und TransitionManager zugleich zu finden?

Mein 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> 

Mein Adapter ist recht einfach:

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

Dann ist mein PageTransformer ist, die jeweils Kinder der Ansicht

meine Aktivität
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; 
    } 
    } 
} 

Und schließlich unabhängig bewegt:

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

Schließlich ist hier ein gif zeigt was passiert. Wie Sie sehen, hat "Item 1" am Anfang den Parallax-Effekt. Nach dem Umschalten zwischen den Szenen wird der PageTransformer nicht mehr angewendet.

Vielen Dank im Voraus!

Issue in action

Antwort

0

Ich werde meine eigene Frage, falls jemand würde stoßen in das gleiche Problem beantworten, wie ich es tat. Das Problem kam von der rootLayout, die ich in dem Fragment nicht "der richtige" war, daher die TransitionManager war eine zusätzliche Schicht hinzufügen, wenn Sie zurück zur ersten Szene.

Hier ist, was ich geändert:

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

Da ich eine andere Schicht in meine Hierarchie hinzugefügt, musste ich auch meine etwas PageTransformer ändern:

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