如何使用从 RecyclerView 到 Fragment 的共享转换

肖恩

我已经看到这个问题在这里问了很多次没有答案。我希望如果我再问一次,也许有人会好心地帮助我。

我正在尝试实现从 Recyclerview 中的项目到片段的共享转换。

我目前在适配器的 onBindView 方法中有我的片段事务。

public void onClick(View v) {
    ...
    activity.getSupportFragmentMnager().beginTransaction()
            .addSharedElement(v, "SharedString")
            .replace(R.id.container, fragment2)
            .addToBackStack(null)
            .commit();
}

android docs 中, addSharedElement(view and string) 让我感到困惑。我如何给视图一个唯一的 ID,我应该在这里使用 v 吗?

字符串可以是我想要的吗?

阿什基罗夫

这是我的实现。FragmentListRecyclerView用在每个项目上的图像。并且FragmentDetail只有在大图像上才有。来自FragmentList列表项的图像飞到FragmentDetailTransitionName的动画视图FragmentListFragmentDetail必须相同。所以我为每个列表项 ImageView 指定了唯一的过渡名称:

imageView.setTransitionName("anyString" + position)

然后我将该字符串传递给FragmentDetailviasetArguments并将大图像transitionName设置为该字符串。我们还应该提供Transition描述从一个视图层次结构的视图如何动画到另一个视图层次结构。之后我们应该将它传递transition给片段。我以前这样做FragmentTransaction

 detailFragment.setSharedElementEnterTransition(getTransition());
 detailFragment.setSharedElementReturnTransition(getTransition());

或者你可以覆盖getSharedElementEnterTransitionand getSharedElementReturnTransitionofFragmenttransition在那里声明这是完整的代码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(savedInstanceState == null) {
            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.fragment_container, new FragmentList())
                    .commit();
        }
    }

    public void showDetail(View view) {
        String transitionName = view.getTransitionName();

        FragmentDetail fragment = new FragmentDetail();
        fragment.setArguments(FragmentDetail.getBundle(transitionName));
        fragment.setSharedElementEnterTransition(getTransition());
        fragment.setSharedElementReturnTransition(getTransition());

        getSupportFragmentManager()
                .beginTransaction()
                .addSharedElement(view, transitionName)
                .replace(R.id.fragment_container, fragment)
                .addToBackStack(null)
                .commit();
    }

    private Transition getTransition() {
        TransitionSet set = new TransitionSet();
        set.setOrdering(TransitionSet.ORDERING_TOGETHER);
        set.addTransition(new ChangeBounds());
        set.addTransition(new ChangeImageTransform());
        set.addTransition(new ChangeTransform());
        return set;
    }
}

活动_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" />

片段列表:

public class FragmentList extends Fragment {

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_list, container, false);
        RecyclerView rv = view.findViewById(R.id.recyclerview);
        rv.setAdapter(new ListAdapter());
        return view;
    }

    private class ListAdapter extends RecyclerView.Adapter {
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
            return new Holder(view);
        }

        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            Holder hold = (Holder) holder;
            hold.itemView.setOnClickListener(v -> {
                ((MainActivity) getActivity()).showDetail(hold.imageView);
            });
            //unique string for each list item
            hold.imageView.setTransitionName("anyString" + position);
        }

        @Override
        public int getItemCount() {
            return 10;
        }

        private class Holder extends ViewHolder {
            ImageView imageView;

            public Holder(View view) {
                super(view);
                imageView = view.findViewById(R.id.image);
            }
        }
    }
}

片段列表.xml

<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/recyclerview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

片段详细信息:

public class FragmentDetail extends Fragment {
    private static final String NAME_KEY = "key";

    public static Bundle getBundle(String transitionName) {
        Bundle args = new Bundle();
        args.putString(NAME_KEY, transitionName);
        return args;
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_detail, container, false);
        String transitionName = getArguments().getString(NAME_KEY);
        ImageView imageView = view.findViewById(R.id.image);
        imageView.setTransitionName(transitionName);
        return view;
    }
}

fragment_detail.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <ImageView
        android:id="@+id/image"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:src="@drawable/cat"/>
</LinearLayout>

项目.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center">

    <ImageView
        android:id="@+id/image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/cat"/>
</LinearLayout>

这是结果:

在此处输入图片说明

TransitionName可能是您想要的任何字符串。还有ViewCompat.setTransitionName,如果你需要支持预棒棒糖设备。

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Android MVVM RecyclerView ClickListener Kotlin到Java的转换

使用Fragment中的按钮在recyclerview内部发送数据

如何使用片段开始共享元素转换?

使用NavController时,如何将数据从目标Fragment的FloatingActionButton的OnClickListener传递到起始Fragment?

RecyclerView中的共享元素转换

如何制作从ViewPager到另一个Fragment的共享过渡动画?

在Fragment中使用RecyclerView时出现Kotlin错误的Android

如何避免将FragmentX绑定到Fragment

如何导航到Half Fragment?(导航架构组件)

如何使用Android导航组件实现从RecyclerView项到Fragment的共享过渡元素?

如何使用MVVM在Fragment内运行的RecyclerView中显示项目?

如何转换LinkedIn API以将内容从OAuth 1.2共享到OAuth2

如何根据recyclerview的OnClickListener位置更改父Fragment和RecyclerView的视图的颜色

如何转换 JSON 数组以在 RecyclerView 中使用

将数据从 Recyclerview 适配器传递到 Fragment

如何防止 RecyclerView Items 在按下后重复并进入设置 RecyclerView 的 Fragment

如何在 Android 中将字符串数组从 RecyclerView Adapter 传递到 Fragment

使用 LiveData 从 Fragment 内部操作 RecyclerView 中的数据

从网格 RecyclerView 到详细活动的共享过渡效果

在 Android 中使用 RecyclerView 保存/恢复 Fragment 状态

RecyclerView 滑动删除 Fragment?

如何从 Activity 到 Fragment 进行通信?

当RecyclerView的内容改变时如何重绘它的父Fragment

在 RecyclerView 的 ViewHolder 的布局中使用 <fragment> 标签可以吗?

如何将参数从 Activity 传递到 Fragment 中的函数

如何使用/转换 sed 到 Python?

如何从 MainActivity 到 Fragment?

Kotlin:如何从 Fragment 导航到 Activity

如何在 Kotlin 中對 Activity 和 Fragment 使用相同的 RecyclerView 適配器?