【问题标题】:Android : transfer a view from a parent to another oneAndroid:将视图从父级转移到另一个
【发布时间】:2020-07-13 06:19:24
【问题描述】:

我来这里帮忙,因为我完全不明白我的代码不起作用。 快一点,我的目标是“重新加载”一个表示列表项的视图。由于我的列表项可以在其子项中包含其他列表项,因此我想扩充一个新的列表项,然后将这些子项从旧项转移到新项。

我得到一个“指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。”错误,但我确实在孩子的父母上调用了 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
    }

感谢阅读!

【问题讨论】:

    标签: java android kotlin view


    【解决方案1】:

    我发现出了什么问题。 当调用 removeView() 时,android 会尝试对其进行动画处理,从而将子视图放入包含当前正在动画的子视图的变量中。然后,当尝试更改子视图的父视图(我们希望为空)时,它会检查当前视图是否正在动画。确实,父母没有改变(至少现在,我不知道以后是否会改变)。这就是为什么我们不能调用 addView()。

    解决办法是把 LayoutTransition 类存起来,然后设置为 null,做传输,然后重置。它不会为孩子们设置动画,但至少它会起作用。

    这里有一小段代码来完成这项工作:

    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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-27
      • 1970-01-01
      • 1970-01-01
      • 2019-07-06
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      相关资源
      最近更新 更多