【问题标题】:Shared element transitions - fragments共享元素转换 - 片段
【发布时间】:2015-05-27 17:57:57
【问题描述】:

我已经在这里推送了我的示例应用程序:https://bitbucket.org/user1010/transitiondemo

我在我的应用程序中遵循主从模式。主片段 (MyRecyclerFragment / MyListFragment) 显示文本视图列表。当用户单击任何这些文本视图时,将启动详细信息片段 (MyDetailsFragment)。详细信息片段具有标题(与用户单击的标题相同)。

我正在尝试实现如下过渡效果:

  • 为现有视图展开过渡
  • 出现视图的淡入淡出过渡
  • 在这 2 个片段之间共享的 TextView 的移动/翻译转换

问题:

  • 当过渡开始时,共享的 TextView 会消失。但是,如果单击列表的第一项,共享转换就会奇迹般地起作用。
  • 如果更改详细信息布局,则过渡有效。请参阅details.xml。如果我完全删除 FrameLayout title_bar 并将 TextView title 作为根 LinearLayout 的直接子级,则共享元素过渡效果很好。
  • 似乎震中因共享元素 return 过渡而发生了变化。例如,如果我单击列表中的第 7 个 TextView,退出转换(爆炸)会将该 TextView 作为震中。它上面的所有TextViews 向上滑动,它下面的TextViews 向下滑动。但是在从细节片段返回到主片段时,返回过渡的中心不是被点击的 TextView。

【问题讨论】:

    标签: android android-fragments android-transitions shared-element-transition fragment-transitions


    【解决方案1】:
    • 当过渡开始时,共享的 TextView 会消失。但是,如果单击列表的第一项,共享转换就会奇迹般地起作用。
    • 如果更改详细信息布局,则过渡有效。请参阅 details.xml。如果我完全删除 FrameLayout title_bar 并将 TextView 标题作为根 LinearLayout 的直接子级,则共享元素过渡效果很好。

    似乎细节 TextView 不能在其父边界之外进行动画处理。尝试将 clipChildren 设置为 false 到您的 details.xml 中的 TextView 的所有父视图,如下所示。它对我有用。

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:clipChildren="false"
                  android:orientation="vertical">
    
        <FrameLayout
            android:id="@+id/title_bar"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:clipChildren="false">
    
            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:background="@android:color/white"
                android:gravity="center"
                android:text="@string/dummy_title"
                android:textColor="@android:color/black"/>
        </FrameLayout>
        ...
    </LinearLayout>
    

    【讨论】:

      【解决方案2】:

      试试这个 -

      为每一行图像设置不同的过渡名称-

       @Override
          public View getView(int position, View convertView, ViewGroup parent) {
      
              View view = convertView;
      
              if (view == null) {
                  view = LayoutInflater.from(getContext()).inflate(R.layout.list_item, null);
              }
      
              TextView textView = (TextView) view.findViewById(R.id.textView);
      
              ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
      
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                  textView.setTransitionName("transtext" + position);
                  imageView.setTransitionName("transition" + position);
              }
      
              return view;
          }
      }
      

      然后在项目上单击例如 -

       ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
                  TextView textView = (TextView) view.findViewById(R.id.smallerImageView);
      
                  EndFragment endFragment = new EndFragment();
      
                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      
                      imageTransitionName = imageView.getTransitionName();
                      textTransitionName = textView.getTransitionName();
      
      
      
       setSharedElementReturnTransition(TransitionInflater.from(
                              getActivity()).inflateTransition(R.transition.change_image_trans));
      
      
        setExitTransition(TransitionInflater.from(
                          getActivity()).inflateTransition(android.R.transition.fade));
      
                  endFragment.setSharedElementEnterTransition(TransitionInflater.from(
                          getActivity()).inflateTransition(R.transition.change_image_trans));
                  endFragment.setEnterTransition(TransitionInflater.from(
                          getActivity()).inflateTransition(android.R.transition.fade));
      
                  }
      
       Bundle bundle = new Bundle();
      
              FragmentManager fragmentManager = getFragmentManager();
      
                  bundle.putString("TRANS_NAME", imageTransitionName);
                  bundle.putString("TRANS_TEXT", textTransitionName);
                  endFragment.setArguments(bundle);
      
                  fragmentManager.beginTransaction()
                          .replace(R.id.container, endFragment)
                          .addToBackStack("Payment")
                          .addSharedElement(imageView, imageTransitionName)
                          .addSharedElement(textView, textTransitionName)
                          .addSharedElement(staticImage, getString(R.string.fragment_image_trans))
                          .commit();
      

      在 oncreate 方法的 EndFragment 中获取转换名称的键并在视图上设置 -

       public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                   Bundle savedInstanceState) {
              Bundle bundle = getArguments();
              String actionTitle = "";
              Bitmap imageBitmap = null;
              String transText = "";
              String transitionName = "";
      
              if (bundle != null) {
                  transitionName = bundle.getString("TRANS_NAME");
                  actionTitle = bundle.getString("ACTION");
                  imageBitmap = bundle.getParcelable("IMAGE");
                  transText = bundle.getString("TRANS_TEXT");
              }
      
              getActivity().setTitle(actionTitle);
              View view = inflater.inflate(R.layout.fragment_end, container, false);
      
              if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                  view.findViewById(R.id.listImage).setTransitionName(transitionName);
                  view.findViewById(R.id.smallerImageView).setTransitionName(transText);
              }
      
              ((ImageView) view.findViewById(R.id.listImage)).setImageBitmap(imageBitmap);
              ((TextView) view.findViewById(R.id.smallerImageView)).setText(actionTitle);
      
              return view;
          }
      

      相关https://stackoverflow.com/a/31982516/3150663

      如果您有解决方案,请投票支持我的答案。 :)

      【讨论】:

      • 如果这两个问题相同,则应将它们作为重复问题关闭。如果不是,那么您应该在此处提供完整的答案,而不是仅提供链接的答案。
      猜你喜欢
      • 2015-08-06
      • 1970-01-01
      • 2015-05-15
      • 1970-01-01
      • 2015-01-30
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      相关资源
      最近更新 更多