「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」
之前的页面太死板,浏览器肯定要支持多页面,本篇文章写一个TransitionManagelementser过渡动画的使用 提升用户体验感
效elementui果图
新建一个WebTabManagerFragment类放入RecyclerViewhttp协议
WebTabManageelement是什么意思rFragment.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF242424">
<FrameLayout
android:id="@+id/list_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
动态创建一个RecyclerView
GridLayout的RecyclerView
private val ALBUM_RECYCLER_VIEW_ID = ViewCompat.generateViewId()
private fun createRecyclerView(listTypeGrid: Boolean): RecyclerView {
val context = requireContext()
//动态创建
val recyclerView = RecyclerView(context)
recyclerView.id = ALBUM_RECYCLER_VIEW_ID
recyclerView.layoutParams =
FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT
)
val verticalPadding = 8
recyclerView.setPadding(0, verticalPadding, 0, verticalPadding)
recyclerView.clipToPadding = false
recyclerView.layoutManager = GridLayoutManager(context, GRID_SPAN_COUNT)
return recyclerView
}
在ReappreciatecyclerView的Aelement酒店dapter写个点击接口用来传条目的点击事件
interface Listener {
fun onClicked(view: View, data: HomeTabEntity)
}
在点击事件下把点击的View传出来
这个view要用来当过度动画的开始标记
container.setOnClickListener {
listener.onClicked(
container,
data
)
}
实现接口的抽象方法
override fun onClicked(view: View, data: HomeTabEntity) {
}
使过渡来动画应appointment用在RecyclerViews 的移除和添加
val recyclerView = createRecyclerView(listTypeGrid)
// 恢复 RecyclerView 的滚动位置)
if (listState != null) {
recyclerView.layoutManager!!.onRestoreInstanceState(listState)
listState = null
}
transition.addTarget(recyclerView)
val currentRecyclerView = listContainer.getChildAt(0)
if (currentRecyclerView != null) {
transition.addTarget(currentRecyclerView)
}
TransitionManager.beginDelayedTransition(listContainer, transition)
插入7条假数据
val albums: List<HomeTabEntity?> = ArrayList<HomeTabEntity>(
Arrays.asList(
HomeTabEntity(1L, "baidu1", "time"),
HomeTabEntity(2L, "baidu2", "time"),
HomeTabEntity(3L, "baidu3", "time"),
HomeTabEntity(4L, "baidu4", "time"),
HomeTabEntity(5L, "baidu5", "time"),
HomeTabEntity(6L, "baidu6", "time"),
HomeTabEntity(7L, "baidu7", "time"),
)
)
adapter.submitList(albums)
Fragment与 Fappearragment的替换
使用 Hold 过渡使该片段在过渡到专辑详细信息屏幕的 MaterialContainerTransform 下方可见。
如果没有 Hold,该 FraElementgment 将在其容器approach被新 Frapproachagment 替换后立即消失将根视图添加为保留的目标,以便将整个视图层次结构作为
一个视图,elementanimation而不是每个子视图。有助于在过渡期间保持阴影。
val fragment = HomeFragment.newInstance(data.title!!)
val transform = MaterialContainerTransform(requireContext(), /* entering= */true)
transform.duration = 666//持续时间/毫秒
fragment.sharedElementEnterTransition = transform
val hold = Hold()
hold.addTarget(R.id.container)//布局标签
hold.duration = transform.duration
//退出的过度动画
exitTransition = hold
拿到父布http协议局的fragment管理器打开搜索页面
parentFragmentManager
.beginTransaction()
.addSharedElement(view, ViewCompat.getTransitionName(view)!!)
.replace(R.id.fragment_container, fragment,HomeFragment.TAG)
.addToBackStack(MainFragment.TAG)
.commit()
在HomeFragment搜索页面的构造函数里面新增一个参数
companion object {
const val TAG = "HomeFragment"
private const val KEY_TRANSITION_NAME = "key_ttansition_name"
fun newInstance(
transitionName:String,
): HomeFragment {
return HomeFragment().apply {
arguments = bundleOf(
KEY_TRANSITION_NAME to transitionName,
)
}
}
}
完整代码
private fun startFragment(
hometab: HomeTabEntity,
view: View
) {
val fragment = HomeFragment.newInstance(hometab.title!!, hometab.id!!)
val transform = MaterialContainerTransform(requireContext(), /* entering= */true)
transform.duration = 666
fragment.sharedElementEnterTransition = transform
val hold = Hold()
hold.addTarget(R.id.container)
hold.duration = transform.duration
exitTransition = hold
parentFragmentManager
.beginTransaction()
.addSharedElement(view, ViewCompat.getTransitionName(view)!!)
.replace(R.id.fragment_container, fragment, MainFragment.TAG)
.addToBackStack(MainFragment.TAG)
.commit()
}
拿到参数之后在onViewCreated下为共享元素转换设置与要转换的开始布appearance局匹配的转换名称
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
arguments?.let { args ->
transitionName = args.getString(KEY_TRANSITION_NAME)
}
if (transitionName != null) {
val transitionNameView :ViewGroup = view.findViewById(R.id.fragment_container)
ViewCompat.setTransitionName(transitionNameView, transitionName)
}
}
最后点击接口的回调下使用
override fun onClicked(view: View, hometab: HomeTabEntity) {
startFragment(hometab, view)
}