一个视图如何检测到它被附加到其父视图?

16

我有一个视图,需要检测它是否已被连接到其父视图。

在一个 ViewGroup 中,我有 OnHierarchyChangeListener,它允许我知道何时添加/移除子视图,但我需要相反的功能。


我以为这只是 onAttachedToWindow - Blundell
我看了一下这个函数,但它似乎并不完全符合我的需求。从我的理解来看,它只有在视图即将绘制自身时才会被调用,但我需要知道它何时被添加到父级容器中,这可能比绘制过程早得多。另外,如果该视图被移除并添加到另一个父级容器中,我不确定该函数的行为会怎样。它会再次被调用吗? - user940016
onDetach将被调用,然后是onAttach,你可以覆盖它们并添加日志记录来找出问题。 - Blundell
可能是添加到父视图的通知?的重复问题。 - kyay10
6个回答

19

你可以创建自定义视图并在其onAttachedToWindow中执行操作

public class CustomView extends View {

   public CustomView(Context context) {
       super(context);
   }

   @Override
   protected void onAttachedToWindow() {
       super.onAttachedToWindow();
       Log.d("CustomView", "onAttachedToWindow called for " + getId());
       Toast.makeText(getContext(), "added", 1000).show();
   }
}

[编辑 1]

您可以确保将自定义视图添加到您想要的正确视图组中

@Override
 protected void onAttachedToWindow() {
    // TODO Auto-generated method stub
    super.onAttachedToWindow();

    if(((View)getParent()).getId()== R.id.relativelayout2)
    {           
        Log.d("CustomView","onAttachedToWindow called for " + getId());
        Toast.makeText(context, "added", 1000).show();          
    }

}

1
但是当视图被构建时,它并没有被添加到父视图中!我想知道当某个视图组调用addView并将该视图作为参数传递时。 - user940016
请参考我上面的评论。我不确定onAttachedToWindow是否是解决我的问题的正确方法。 - user940016
针对您的问题,您应该同时控制父级元素,您可以查看编辑后的答案。 - Talha

3
如果您正在使用 kotlin,则可以在 View 上使用 doOnAttach 扩展函数。
    view.doOnAttach {
        // TODO: Your view has a parent, you can use it now.
        (view.parent as ViewGroup)?.yourAction()
    }

3

无需创建自定义视图的解决方案

如果您不能或不想修改视图,则可以使用View.addOnAttachStateChangeListener 在视图附加到视图层次结构和从视图层次结构分离时获取钩子。

类似于以下内容:

Kotlin

view.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
  override fun onViewAttachedToWindow(v: View) {
    // Do stuff when view has been attached to window
  }

  override fun onViewDetachedFromWindow(v: View) {
    // Do stuff when view has been detached from window
  }
})

Java

view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
  @Override
  public void onViewAttachedToWindow(View v) {
    // Do stuff when view has been attached to window
  }

  @Override
  public void onViewDetachedFromWindow(View v) {
    // Do stuff when view has been detached from window
  }
});

0
你可以从不同的角度看待这个问题,如果你通过实现onViewAdded方法来监视父视图中的附加视图。
例如:
public class LayoutInvokeChildAdded extends RelativeLayout {

    private OnDoneListener onDoneListener;

    public LayoutInvokeChildAdded(Context context) {
        super(context);
    }

    public LayoutInvokeChildAdded(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public LayoutInvokeChildAdded(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void onViewAdded(View child) {
        super.onViewAdded(child);
        if (onDoneListener != null)
            onDoneListener.onDone(childe);
    }

    public void setOnDoneListener(OnDoneListener onDoneListener) {
        this.onDoneListener = onDoneListener;
    }
}

0

嗯,你在OnHierarchyChangeListener中有视图,所以我想你可以通过使用接口对视图进行子类化并从OnHierarchyChangeListener调用它来添加回调。这样,当OnHierarchyChangeListener被调用时,你的视图也将被同时调用。

然而,当这种情况发生时,你的视图的许多属性,如它们的尺寸可能尚未定义,这一点不足为奇。


当然,这对于父母来说并不是一个自动化的过程。 - SylvainL

0

我认为,如果您需要那种控制,最好将其作为一个片段。这样,您就可以访问更精细的生命周期。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接