带有PageTransformer和SceneTransition的Android ViewPager

西蒙

并感谢您的光临。

我一直在使用面临着两者的组合怪异的行为PageTransformerTransitionManager

我使用的层次是相当容易:一个viewPager与每一页是一个fragment该片段有两种不同的布局,随改变TransitionManager.go()

问题:如果我只是滚动浏览viewPager,一切都很好,而我的pageTransformer会应用正确的值,从而创建所需的视差效果。如果仅单击来回更改页面内的场景,我还将获得所需的输出。

但是,每当我使用TransitionManager.go()(让我们说两次,回到第一个布局)然后开始在viewPager中滚动时,就不会再出现视差效果了。

我的问题:是否同时使用aPageTransformer和a找不到任何已知问题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将不再适用。

提前致谢 !

行动中的问题

西蒙

如果有人遇到与我相同的问题,我将回答我自己的问题。问题来自我在片段中使用的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;
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Android的ViewPager.PageTransformer

来自分类Dev

带有ViewPager的Android RecyclerView

来自分类Dev

使用PageTransformer的嵌套片段中带有ViewPager的dispatchDraw上的NullpointerException

来自分类Dev

带有Fragment和ViewPager的NullPointerException

来自分类Dev

带有ViewPager和TextView的奇怪的IllegalStateException

来自分类Dev

带有 viewpager 活动和片段的 onBackPressed

来自分类Dev

Android ViewPager和EditText

来自分类常见问题

带有底点的Android ViewPager

来自分类Dev

带有ViewPager Android的固定标签

来自分类Dev

Android服务>活动>带有ViewPager的片段

来自分类Dev

带有片段的Android ViewPager

来自分类Dev

带有viewPager的Android多RecyclerView

来自分类Dev

具有支持库v13的ViewPager PageTransformer

来自分类Dev

具有多个PageTransformer的ViewPager(运行时为PageTransformers)

来自分类Dev

带有TabLayout的无限ViewPager

来自分类Dev

Android中的片段和ViewPager

来自分类Dev

Android:ScollView和ViewPager的问题

来自分类Dev

ViewPager 和 Android Wear = 崩溃

来自分类Dev

ViewPager和YouTubePlayer

来自分类Dev

ViewPager和片段问题

来自分类Dev

后退按钮和ViewPager

来自分类Dev

Viewpager和片段问题

来自分类Dev

BottomSheet与ViewPager和片段?

来自分类Dev

ViewPager和DepthPageTransformer

来自分类Dev

ViewPager和片段错误

来自分类Dev

问:ViewPager和OnClickListener

来自分类Dev

ViewPager和PageTitleStrip

来自分类Dev

后退按钮和ViewPager

来自分类Dev

BottomSheet与ViewPager和片段?