【问题标题】:How can a view detect when it's being attached to its parent?视图如何检测它何时附加到其父级?
【发布时间】:2012-12-28 11:13:01
【问题描述】:

我有一个视图需要检测它何时附加到其父视图。

ViewGroup 中,我有OnHierarchyChangeListener,它可以让我知道何时添加/删除子视图,但我需要相反的东西。

【问题讨论】:

  • 我以为只是onAttachedToWindow
  • 我阅读了有关该功能的信息,但它似乎并不完全符合我的需要。据我了解,它仅在视图即将绘制自身时调用,但我必须知道它何时添加到父级,这可能在绘图过程开始之前发生。另外,如果视图被删除并添加到另一个父级,我不确定这个函数的行为。它会再次被调用吗?
  • onDetach 将被调用,然后 onAttach,如何覆盖它们并自己添加日志以找出答案

标签: android android-layout android-view


【解决方案1】:

您可以创建自定义视图并在其 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();          
    }

}

【讨论】:

  • 但是视图在构建时并没有添加到父视图中!我想知道什么时候在某个视图组上调用 addView 并将此视图作为参数传递。
  • 请看我上面的评论。我不确定 onAttachedToWindow 是否适合我的问题。
  • 对于您的问题,您也应该控制父母,您可以查看编辑后的答案
【解决方案2】:

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

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

类似:

科特林

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
  }
});

【讨论】:

    【解决方案3】:

    好吧,您在 OnHierarchyChangeListener 中有视图,所以我想您可以为您的视图添加一个回调(通过使用接口对它们进行子类化)并从 OnHierarchyChangeListener 中调用它。这样,您的视图将在调用 OnHierarchyChangeListener 的同时被调用。

    但是,当这种情况发生时,您的视图的许多属性(例如它们的尺寸)可能尚未定义,我不会感到惊讶。

    【讨论】:

    • 是的,当然:这对父母来说不是一个自动的过程。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      如果您通过实现方法 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;
          }
      }
      

      【讨论】:

        【解决方案6】:

        如果您使用的是 kotlin,您可以在 View 上使用 doOnAttach 扩展功能。

            view.doOnAttach {
                // TODO: Your view has a parent, you can use it now.
                (view.parent as ViewGroup)?.yourAction()
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-01-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-21
          • 1970-01-01
          • 1970-01-01
          • 2011-06-08
          相关资源
          最近更新 更多