2016-04-19 3 views
2

и благодарю вас за то, что вы остановились.Android ViewPager с PageTransformer и SceneTransition

Я столкнулся с странным поведением, используя комбинацию как PageTransformer, так и TransitionManager.

Иерархия, которую я использую, довольно проста: A viewPager с каждой страницей fragment. Фрагмент имеет два разных макета, изменяющихся с помощью TransitionManager.go().

Вопрос: Если я просто пролистать ViewPager, все хорошо, и мой pageTransformer применяет правильные значения, создавая желаемый эффект параллакса. Если я просто нажимаю кнопку «назад» и «вперед», чтобы изменить сцены внутри страницы, я также получаю желаемый результат.

Однако, когда я использую TransitionManager.go() (скажем дважды, чтобы вернуться к первому расположению), а затем начать прокрутку через мой viewPager, эффект параллакса больше не встречается.

Мой вопрос: Есть ли известная проблема, я не смог найти с использованием как PageTransformer и TransitionManager в то же время?

Мой код:

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

Тогда мой PageTransformer, которая движется каждый детей представления независимо

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

И, наконец, моя активность:

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 добавлял дополнительный слой при возвращении к первой сцене.

Вот что я изменил:

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

Поскольку я добавил еще один слой в моей иерархии, я также должен был немного изменить мой 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; 
     } 
    } 
} 
Смежные вопросы