我正在处理一些片段,但是从一个片段切换到另一个片段时的过渡动画非常滞后,有时甚至会跳过整个动画(我已经读过,有时这是片段性能不佳的结果)。
非常有趣的是,我在该片段中的所有数据获取和计算都是使用设置在计算线程上的协程完全异步完成的。包含数据的数组列表甚至不长或有很多参数。我在 UI 上做的唯一一件事就是在 RecyclerView Adapter 和 notifyDataSetChanged() 上设置最终列表 -> 就是这样!所以我的结论是 ViewHolder 膨胀本身就是导致滞后的原因。ViewHolders 的布局 XML 也非常精简(一个可绘制资源和三个字符串)。
在片段事务方面,我将当前片段替换为 FrameLayout 中的新片段,并使用一组自定义的 XML 对象动画器进行提交。
我已经看到一些答案说我应该将适配器上的项目设置延迟大约 2 秒钟,但是见鬼,最终用户在该片段中导航并在白屏上等待 2 秒钟之前看起来真的很糟糕数据突然出现。我想要一个平滑的 60fps 过渡到新片段,数据已经显示。
这件事在Android上甚至可能吗?我不是苹果迷,但就动画的流畅度和流畅度而言,iOS 设备在这个主题上破坏了 Android 的混乱局面。
我需要任何类型的建议甚至示例来向我展示如何解决此问题。
谢谢!
animation android fragment fragmenttransaction fragmentmanager
我终于开始使用 Android 版 Compose,但目前陷入导航困境。我有两个问题:
1. 我实现了带有三个按钮的底部导航,其中一个按钮触发嵌套导航图,例如:
HOME --- CONTACTS --- FAVOURITES
|
DETAILS
Run Code Online (Sandbox Code Playgroud)
因此,当我从主页打开详细信息屏幕并切换选项卡时,行为是正确的,嵌套图中的状态和最后目的地会被记住,当我再次点击主页时,它会保留状态并切换回详细信息。但是,如果我在任何其他选项卡上并按返回,它会将我带回到主页,但会重置状态,不会让我返回详细信息。我怎样才能做到这一点?
导航栏:
@Composable
fun BottomNavigationBar(navController: NavHostController) {
BottomNavigation {
val backStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = backStackEntry?.destination?.route
BottomNavigationCollection.items.forEach { navItem ->
BottomNavigationItem(
selected = currentRoute == navItem.route,
onClick = {
navController.navigate(navItem.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
},
icon = {
Icon(
imageVector = navItem.icon,
contentDescription = navItem.title
)
},
label = {
Text(text = navItem.title)
},
)
} …Run Code Online (Sandbox Code Playgroud) 我的应用程序上下文,以便您可以理解我的问题:
我目前正在编写一个非常复杂的应用程序,其中包含一个巨大的仪表板,其中包含大量嵌套的 RecyclerView(水平和垂直)。我知道垂直房车内的垂直房车是一种不好的做法,但不幸的是,这里的管理层和客户的要求比我们的建议更强烈,他们真的希望它得到实施。我们是如何获得垂直房车中的垂直房车的?我们的后端基本上提供了需要在仪表板内呈现的组的数组列表。基本上是服务器驱动的用户界面。这些组包含各种不同的设计、垂直子列表、水平子列表等。到目前为止,我已经成功地为这个 DashBoard 适配器构建了一个原型,现在我想更深入地了解性能优化。
我尝试过提高性能的事情:
我已经实现了 DiffUtil 来使仪表板在数据刷新时更有效地更新。我已将适配器设置为使用每个组都有的稳定 ID 和唯一的哈希值。我已经使用constraintLayout创建了平面UI,并且布局可能绝对最少。我已经使用了数据绑定,事实证明它实际上只提高了一点性能,而不仅仅是更好的干净代码。我绝对没有在适配器或 viewHolder 中进行任何数据处理,整个数据流具有来自更高数据层的最终形状。我已
linearLayoutManager.initialPrefetchItemCount = x在每个嵌套 RV 上设置,其中 x 是在任何滚动之前在屏幕上呈现的项目数。
然后我遇到了 RecycledViewPool。我见过一些人们用这个技巧提高列表性能的例子。基本上,他们获取父大适配器的 recyclerViewPool 并将其设置在嵌套的 RV 上。我也实现了这个,我的大问题是现在我所有的嵌套项目都完全混淆了。
而不是像这样拥有三个水平房车:
现在我把它们都混在一起了,如下所示:
这是我的recycledViewPool实现:
class GlobalAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val groups: ArrayList<Group> = ArrayList()
private var recyclerViewPool = RecyclerView.RecycledViewPool()
[...]
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
CATEGORIES_LIST.typeText.hashCode() -> {
val holder = CategoryGroupViewHolder(
DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.group_item_categories_list, parent, false
), adapterCallback
)
holder.binding.recyclerView.setRecycledViewPool(recyclerViewPool)
holder
}
[...]
Run Code Online (Sandbox Code Playgroud)
所以我基本上将 viewPool …
android adapter kotlin android-recyclerview nestedrecyclerview
我有一个关于扩展功能的简短问题,该功能可以帮助清除一些代码。基本上,我对类名的hashCode进行了一些转换,并且我希望扩展函数执行这些转换。
例:
获得名称hashCode:StateA::class.java.name.hashCode()其中StateA是一个简单的类。
我想要扩展功能,如:
fun Class<*>.transformName(): String {
var hashString = this.javaClass.name.hashCode()
//Do my stuff on that hashString
return hashString
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用。当我使用扩展功能时StateA.transformName(),该功能给我未解析的引用带来了错误。
我尝试了各种操作,例如将函数应用于StateA::class或使hashString等于,this::class.java.name.hashCode()但无济于事。有小费吗?