作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我来这里寻求帮助,因为我根本不明白我的代码不起作用。简而言之,我的目标是“重新加载”代表列表项的 View 。由于我的列表项可以在其子项中包含其他列表项,因此我想扩充一个新列表项,然后将这些子项从旧列表项转移到新列表项。
我收到“指定的子项已经有父项。您必须首先在子项的父项上调用removeView()。”错误,但我确实在 child 的 parent 上调用了removeView(不知怎的,它不起作用)(见我的代码)
这是我的布局的设计方式(我删除了一些行,以便更容易阅读):
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="mainListItem"
type="com.plg.lirs.data.LirsDataEntity" />
</data>
<LinearLayout android:id="@+id/main_list_item_global_layout">
<LinearLayout android:id="@+id/main_list_item_parent_layout"
app:mainListItemParentLayout="@{mainListItem}">
<!-- contains a bunch of views and stuff, nothing important here -->
</LinearLayout>
<LinearLayout android:id="@+id/main_list_item_children_layout"
android:animateLayoutChanges="true">
<!-- here are all the children i want to transfer, all the children here are inflated from this layout -->
</LinearLayout>
</LinearLayout>
</layout>
现在这是我的代码来膨胀这个布局:
/* entity is just a logical class that contains my data
olderView is the old view representing the old list item */
private fun inflateItem(entity: LirsDataEntity, olderView: View? = null) : View {
val itemBinding = DataBindingUtil.inflate<MainListItemBinding>(inflater, R.layout.main_list_item, null, false, null)
// the itemBinding.root will be added into the parent's children layout later on, after this function
// + i've tried with true as attachToParent, doesn't change
/* HERE is the core of the problem. My goal is : if an olderView is provided, then transfer the children from the old one to the new one */
if(olderView != null) {
val olderChildrenLayout = olderView.findViewById<LinearLayout>(R.id.main_list_item_children_layout) // here is the LinearLayout that contains the children
val children = olderChildrenLayout.children
children.forEach {
olderChildrenLayout.removeView(it) // remove the children from the old parent
itemBinding.mainListItemChildrenLayout.addView(it) // add it to the new parent
// at this point i get the error
}
}
entity.ui.reset() // not important here
itemBinding.mainListItem = entity
/* some listeners are set here */
return itemBinding.root
}
感谢您的阅读!
最佳答案
我发现出了什么问题。当调用removeView()时,android尝试对其进行动画处理,从而将 subview 放入包含当前正在动画处理的 subview 的变量中。然后,当尝试更改 subview 的父 View (我们希望其为空)时,它会检查当前 View 是否正在动画。事实上,父级没有改变(至少现在,我不知道以后是否会改变)。这就是为什么我们无法调用 addView()。
解决方案是存储LayoutTransition类,然后将其设置为null,进行传输,然后重置它。它不会让 children 活跃起来,但至少它会起作用。
这里有一小段代码可以实现这一点:
public class JavaUtils {
public static void transferChildren(@NotNull final ViewGroup depart, @NotNull final ViewGroup arrival) {
LayoutTransition transition = depart.getLayoutTransition();
depart.setLayoutTransition(null);
while(depart.getChildCount() > 0) {
View c = depart.getChildAt(0);
depart.removeViewAt(0);
arrival.addView(c);
}
depart.setLayoutTransition(transition);
}
}
对于 Kotlin 用户:
fun ViewGroup.transferChildrenTo(arrival: ViewGroup) {
val transition: LayoutTransition = layoutTransition
layoutTransition = null
while (childCount > 0) {
val c: View = getChildAt(0)
removeViewAt(0)
arrival.addView(c)
}
layoutTransition = transition
}
关于java - 安卓 : transfer a view from a parent to another one,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60971913/
我是一名优秀的程序员,十分优秀!