Android RemoveView不工作

Android RemoveView不工作,android,viewgroup,Android,Viewgroup,我犯了一个不寻常的错误。我在自定义视图组中有这个。该方法收到一个视图并将其添加到布局中,但我一直收到相同的错误: if((ViewGroup)view.getParent() != null){ ((ViewGroup)view.getParent()).removeView(view); } addView(view); <--- Breakpoints puts the error on this line 在CustomGridLayout视图组类中: public vo

我犯了一个不寻常的错误。我在自定义视图组中有这个。该方法收到一个视图并将其添加到布局中,但我一直收到相同的错误:

if((ViewGroup)view.getParent() != null){
    ((ViewGroup)view.getParent()).removeView(view);
}

addView(view); <--- Breakpoints puts the error on this line
在CustomGridLayout视图组类中:

public void addCustomView(View view){
    if((ViewGroup)view.getParent() != null){
        ((ViewGroup)view.getParent()).removeView(view);
    }

    addView(view);
}

我在尝试创建自定义横幅时也遇到了同样的问题。我相信这是因为布局期间的动画,这就是为什么延迟可以工作的原因。在我的例子中,我创建了一个自定义viewgroup类来消除动画延迟:

private class BannerLayout extends LinearLayout {
  public BannerLayout(Context context) {
     super(context);
  }

  @Override
  protected void removeDetachedView(View child, boolean animate) {
     super.removeDetachedView(child, false);
  }
}
一旦我这样做了,一切都按预期进行


希望有帮助

我也有同样的问题,我的回答对我很有帮助。原因是布局转换的动画,但如果我将其值设置为null,我将丢失转换动画。所以我所做的就是添加一个布局转换监听器,这样你可以在转换完成后监听器,然后将视图添加到它的新父视图中

使用Java

LayoutTransition layoutTransition = ((ViewGroup)view.getParent()).getLayoutTransition();
layoutTransition.addTransitionListener(new TransitionListener(){

    @Override
    public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {

    }

    @Override
    public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
         // now you can add the same view to another parent
         addView(view);
    } 
});
使用Kotlin

val layoutTransition = (view.parent as ViewGroup).layoutTransition
layoutTransition.addTransitionListener(object : LayoutTransition.TransitionListener {

      override fun startTransition(transition: LayoutTransition?,container: ViewGroup?,view: View?,transitionType: Int) {

      }

      override fun endTransition(transition: LayoutTransition?,container: ViewGroup?,view: View?,transitionType: Int) {
         // now you can add the same view to another parent
         addView(view)
      }
})

如果您必须处理具有或不具有
layoutTransition
视图组
,您可以执行以下操作:

/**
 * When we don't have [LayoutTransition] onEnd is called directly
 * Or
 * function [onEnd] will be called on endTransition and when 
 * the parent is the same as container and view parent is null,
 * and will remove also the transition listener
 */
private fun doOnParentRemoved(parent: ViewGroup, onEnd: () -> Unit) {
    val layoutTransition = parent.layoutTransition

    if (layoutTransition == null) {
        onEnd.invoke()
        return
    }

    val weakListener = WeakReference(onEnd)
    layoutTransition.addTransitionListener(object : LayoutTransition.TransitionListener {
        override fun startTransition(
            transition: LayoutTransition?,
            container: ViewGroup?,
            view: View?,
            transitionType: Int
        ) {
        }

        override fun endTransition(
            transition: LayoutTransition?,
            container: ViewGroup?,
            view: View?,
            transitionType: Int
        ) {
            transition?.removeTransitionListener(this)
            weakListener.get()?.invoke()
        }
    })
}
您可以这样使用它:

sourceLayout.removeView(textView)
doOnParentRemoved(sourceLayout) {
   // do your stuff when view has no parent
   // add more logic to check is your view who called it in case of multiple views
}

我建议再次检查您的实现,因为有时可能会发生
endTransition
不能保证被调用,或者动画可能会中途停止。在我的例子中,我在拖放操作中使用了它

您确定调用了removeView吗?这是什么课?为什么在第一种情况下必须使用
getParent()
方法,而在第二种情况下只需调用
addView()
?因为网格是不同的。我在两个网格之间移动childviews,这是我在网格内部调用的方法,用于将视图从一个网格移动到另一个网格,是的,正在调用remove view如何声明
视图
,代码是什么?不确定这是否有帮助,但在添加之前是否尝试调用
视图。invalidate()
?但是您正在发送一个新创建的
视图
(来自您发布的代码),这样它就没有父视图了。我在几个地方调用了addCustomView。。在childs view click事件上,在long click事件etcThanks!我不认为^^在不创建子类的情况下消除动画的另一种方法是将parent的布局转换设置为null,类似这样:
parentView.setLayoutTransition(null);parentView.removeView(视图)
@Chupik需要注意的是
setLayoutTransition(…)
sourceLayout.removeView(textView)
doOnParentRemoved(sourceLayout) {
   // do your stuff when view has no parent
   // add more logic to check is your view who called it in case of multiple views
}