2016-04-19 14 views
2

ありがとうございます。PageTransformerとSceneTransitionを使用したAndroid ViewPager

私はPageTransformerTransitionManagerの組み合わせを使用して奇妙な動作に直面しています。

私が使用している階層はかなり簡単です:viewPager各ページはfragmentです。このフラグメントには、2つの異なるレイアウトがあり、TransitionManager.go()で変更されています。

問題: 私はちょうどviewPagerをスクロールした場合、すべてがうまくある、と私pageTransformerが必要な視差効果を作成し、正しい値を適用します。 ページ内のシーンを前後に変更するだけで、目的の出力も得られます。

しかし、TransitionManager.go()(最初のレイアウトに戻すために2度言うとします)を使用し、次に私のviewPagerをスクロールし始めると、視差効果はそれ以上発生しません。

私の質問:私は同時にPageTransformerTransitionManagerの両方を使用して見つけることができませんでした任意の既知の問題が ありますか?

マイコード:

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> 

私のアダプタは非常に簡単です:

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

はその後

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

そして最後に、私の活動独立ビューのそれぞれの子供たちを動かし、私のPageTransformerです:

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

最後に、ここにあります何が起こるかを示すgif。あなたが見ることができるように、冒頭に "アイテム1"は視差効果を持っています。シーンを前後に切り替えると、PageTransformerはもう適用されません。

ありがとうございます!

Issue in action

答えて

0

私が行ったように、誰もが同じ問題にぶつかるだろう場合には自分の質問にお答えします。 問題は、右のものではないフラグメントで使用していたrootLayoutから来ていたため、TransitionManagerは最初のシーンに戻るときに余分なレイヤーを追加していました。

私が変更したもの:

フラグメント1。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); 
} 

私は私の階層に別のレイヤーを追加しましたので、私も少し私の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; 
     } 
    } 
} 
関連する問題