首先在子节点的父节点上调用 RemoveView()

首先介绍一下背景:

我在滚动视图里有一个布局。首先,当用户在屏幕上滚动时,scrollview 会滚动。然而,在一定数量的滚动后,我是禁用滚动视图上的滚动,将“滚动焦点”移动到子布局中的一个 webview 上。通过这种方式,scrollview 粘贴并且所有的滚动事件都进入其中的 webview。

因此,对于解决方案,当达到滚动阈值时,我从 scrollview 中删除子布局,并将其放在 scrollview 的父级中。(使滚动视图不可见)。

// Remove the child view from the scroll view
scrollView.removeView(scrollChildLayout);


// Get scroll view out of the way
scrollView.setVisibility(View.GONE);


// Put the child view into scrollview's parent view
parentLayout.addView(scrollChildLayout);

概念: (- > 表示包含)

之前: Parentlayout-> scrollview-> scrollChildLayout

After: ParentLayout-> scrollChildLayout

上面的代码给了我这个例外:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:1976)
at android.view.ViewGroup.addView(ViewGroup.java:1871)
at android.view.ViewGroup.addView(ViewGroup.java:1828)
at android.view.ViewGroup.addView(ViewGroup.java:1808)

你知道这是怎么回事吗? 很明显我在调用 RemoveView。

199751 次浏览

首先尝试从其父视图中删除 scrollChildLayout?

scrollview.removeView(scrollChildLayout)

或者从父视图中删除所有子视图,然后再次添加它们。

scrollview.removeAllViews()

您所需要做的就是发布一个可运行的 addView ()。

解决方案:

((ViewGroup)scrollChildLayout.getParent()).removeView(scrollChildLayout);
//scrollView.removeView(scrollChildLayout);

使用子元素获取对父元素的引用。将父类强制转换为 ViewGroup,以便您可以访问 RemoveView 方法并使用该方法。

感谢@Dongshengcn 的解决方案

您也可以通过检查 View 的 indexOfView 方法来完成 如果 indexOfView 方法返回 -1,那么我们可以使用。

ViewGroup 的 detachViewFromParent (v) ; 然后是 ViewGroup 的 RemoveDetachedView (v,true/false) ;

好吧,你可以说我多疑,但我建议:

  final android.view.ViewParent parent = view.getParent ();


if (parent instanceof android.view.ViewManager)
{
final android.view.ViewManager viewManager = (android.view.ViewManager) parent;


viewManager.removeView (view);
} // if

没有 instanceof的选角似乎是错误的。而且(感谢 IntelliJIDEA 告诉我) removeViewViewManager接口的一部分。当一个完全合适的接口可用时,不应该强制转换为具体的类。

我正在调用 ParentView.RemoveView (child View) ,但是 child View 仍然显示。我最终意识到一个方法以某种方式被触发了两次,于是我将 child View 添加到了 ParentView 中两次。

因此,在添加视图之前和之后,可以使用 ParentView.getChildCount ()来确定父视图有多少个子视图。如果子元素被添加了太多次,那么顶部的大部分子元素将被删除,并且复制的 child View 仍然存在——即使在它工作的时候,RemoveView 看起来仍然在工作。

另外,不应该使用 View.GONE 删除视图。如果它真的被移除了,那么你就不需要隐藏它,否则它仍然在那里,你只是在对自己隐藏它:

在 onCreate with activity 中或在 onCreateView 中使用片段。

 if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null) {
parent.removeView(view);
}
}
try {
view = inflater.inflate(R.layout.fragment_main, container, false);
} catch (InflateException e) {


}

我做错了什么,所以我得到了这个错误是我没有实例化动态布局和添加子元素,所以得到了这个错误

在我的例子中,我有 BaseFragment 和从它继承的所有其他片段。

因此,我的解决方案是在 OnDestroyView()方法中添加这些行

@Override
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if (mRootView == null)
{
mRootView = (inflater == null ? getActivity().getLayoutInflater() : inflater).inflate(mContentViewResourceId, container, false);
}
....////
}


@Override
public void onDestroyView()
{
if (mRootView != null)
{
ViewGroup parentViewGroup = (ViewGroup) mRootView.getParent();


if (parentViewGroup != null)
{
parentViewGroup.removeAllViews();
}
}


super.onDestroyView();
}

这是我的解决办法。

假设你有两个 TextViews,把它们放在一个 LinearLayout(名为 ll)上。你把这个 LinerLayout放到另一个 LinerLayout上。

< lm Linear Layout>
< ll Linear Layout>
<name Text view>
</name Text view>
<surname Text view>
</surname Text view>
</ll Linear Layout>
</lm Linear Layout>

当您想要创建这个结构时,您需要给父结构作为继承。

如果你想在 onCreate方法中使用它,this就足够了。

否则,这里就是孤立:

LinerLayout lm = new LinearLayout(this); // You can use getApplicationContext() also
LinerLayout ll = new LinearLayout(lm.getContext());
TextView name = new TextView(ll.getContext());
TextView surname = new TextView(ll.getContext());

Kotlin 溶液

Kotlin 使用 as?简化了父类强制转换,如果左侧为 null 或强制转换失败,返回 null。

(childView.parent as? ViewGroup)?.removeView(childView)

Kotlin 扩展解决方案

如果希望进一步简化,可以添加这个扩展。

childView.removeSelf()


fun View?.removeSelf() {
this ?: return
val parentView = parent as? ViewGroup ?: return
parentView.removeView(this)
}

如果这个视图为 null,父视图为 null,或者父视图不是 ViewGroup,那么它将安全地什么也不做

注意: 如果您还希望父视图安全删除子视图,请添加以下内容:

fun ViewGroup.removeViewSafe(toRemove: View) {
if (contains(toRemove)) removeView(toRemove)
}