gpt4 book ai didi

android - 如何使用recyclerview实现Material Design父子过渡

转载 作者:行者123 更新时间:2023-12-04 09:25:11 24 4
gpt4 key购买 nike

我正在尝试实现这一点

enter image description here

像我之前的其他人一样。

到目前为止我发现:

  • How to implement the "parent-to-child" navigational transition as prescribed by Material Design
  • Material Design parent-child navigational transition recyclerview entry to detail fragment
  • How to create Parent-child transition in which list item lifts out and become details screen
  • Custom fragment transition parent-to-child navigation setExitTransition not showing
  • https://medium.com/@bherbst/fragment-transitions-with-shared-elements-7c7d71d31cbb
  • https://medium.com/@jim.zack.hu/android-inbox-material-transitions-for-recyclerview-71fc7326bcb5
  • https://github.com/saket/InboxRecyclerView
  • https://www.youtube.com/watch?v=EjTJIDKT72M


  • 到目前为止我所做的:

    enter image description here

    父 fragment
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    initViewModel();
    setupRecyclerView();
    initViewModelSubscriptions();
    }

    @Override
    public void onClick(View v, CustomNavigator.Extras extras) {
    Bundle bundle = new Bundle();
    bundle.putString("transitionName", v.getTransitionName());

    NavController navController = NavHostFragment.findNavController(this);
    navController.navigate(R.id.action_devicemgmt_to_deviceMgmtEditFragment,
    bundle, // Bundle of args
    null, // NavOptions
    extras);
    }

    细节 fragment
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Transition t = TransitionInflater.from(getContext()).inflateTransition(R.transition.test).setDuration(1000);
    setSharedElementEnterTransition(t);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    setupToolbar();
    setTransitionName();
    }

    private void setTransitionName() {
    binding.coord.setTransitionName(getArguments().getString("transitionName"));
    }

    R.transition.test
    <?xml version="1.0" encoding="utf-8"?>
    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:transitionOrdering="together"
    android:interpolator="@android:interpolator/fast_out_slow_in">
    <changeBounds/>
    <changeTransform/>
    <changeClipBounds/>
    </transitionSet>

    RecyclerView Adapter的ViewHolder
    static class BindingHolder extends RecyclerView.ViewHolder {

    private final ItemDevicemgmtBinding binding;

    BindingHolder(ItemDevicemgmtBinding binding) {
    super(binding.getRoot());
    this.binding = binding;

    binding.getRoot().setOnClickListener(v -> {
    CustomNavigator.Extras extras = new CustomNavigator.Extras.Builder()
    .addSharedElement(v, v.getTransitionName())
    .build();

    callback.onClick(v, extras);
    });
    }

    void bind(String deviceSn) {
    binding.getRoot().setTransitionName(String.valueOf(getItemId()));
    binding.setVariable(BR.deviceSn, deviceSn);
    binding.executePendingBindings();
    }
    }

    父 fragment 布局
    <androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycler_mgmt_devices"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    </androidx.recyclerview.widget.RecyclerView>

    <include
    android:id="@+id/layout_mgmt_no_devices"
    layout="@layout/layout_mgmt_no_devices"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginBottom="@dimen/bottomappbar_height"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    详细 fragment 布局
    <androidx.coordinatorlayout.widget.CoordinatorLayout
    android:id="@+id/coord"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:title="New Item" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

    <androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/const_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/design_default_color_primary">

    <EditText
    android:id="@+id/editText2"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginTop="16dp"
    android:layout_marginEnd="8dp"
    android:ems="10"
    android:inputType="textPersonName"
    android:text="Serial Number"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.core.widget.NestedScrollView>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    RecyclerView 项目布局
    <androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:clickable="true"
    android:focusable="true"
    android:paddingStart="@dimen/single_line_item_padding_start"
    android:paddingTop="@dimen/single_line_item_padding_top"
    android:paddingEnd="@dimen/single_line_item_padding_end"
    android:paddingBottom="@dimen/single_line_item_padding_bottom">

    <TextView
    android:id="@+id/text_devicemgmtitem_sn"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:text="@{deviceSn}"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/imagebutton_devicemgmtitem_more"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:text="89745897696978456790456456" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    如您所见,sharedEnterTransition 正在工作,但离开 Fragment 时的反向转换不是我所期望的。项目容器被转换,而不是 fragment 容器。 Nick Butcher 在我在第 8 点链接的视频中谈论了这种过渡,但不幸的是,他只解释了滚动功能的崩溃。当我正确理解他时...

    the idea..the previous content is still there..the new screen is lifted up and sitting on top of them



    所以至少有两个单独的屏幕是很清楚的,而 InboxRecyclerView 的创建者是在相同的布局中做的。

    但是在尼克的例子中,他使用的是 Activity ,而我使用的是 fragment ,所以不确定用细节 fragment 替换父 fragment 是否是一个问题?!

    那么有人可以帮助我吗?

    最佳答案

    您必须推迟结束转换,直到 RecyclerView 准备好。幸运的是,我们有两种方便的方法可供使用:
    推迟EnterTransition 和 startPostponedEnterTransition。
    这些允许我们延迟过渡,直到我们知道我们的共享元素已经布局并且可以被过渡系统找到。作为回复,我们可以推迟,直到我们确定我们的 RecyclerView 适配器已被填充并且我们的列表项已使用以下代码段与转换名称绑定(bind):

    postponeEnterTransition()
    view.doOnPreDraw { startPostponedEnterTransition() }

    关于android - 如何使用recyclerview实现Material Design父子过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53218675/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com