添加到父级的View上的通知?

时间:2013-10-09 10:41:52

标签: android android-layout android-view android-custom-view

当我在Android中动态构建View时,我必须通过调用

将其添加到“父”ViewGroup
myLinearLayout.addView(myView);

我知道我可以监督 ViewGroup ,以便通过优秀的onHierarchyChangeListener添加任何孩子,但在我的情况下,我需要中的反馈View 本身。因此我的问题是:

我可以建立一个类似View.onAddedToParent()回调或监听器的东西吗?

为了使事情变得非常明确:我希望视图能够自己处理所有事情,我知道我可以在“父”中捕获事件,然后通知视图有关事情,但这是这里需要。我只能改变观点

编辑:我刚刚找到onAttachStateChangeListener,它似乎适用于大多数情况,但我想知道这是否真的是正确的解决方案。我认为View也可以从一个ViewGroup转移到另一个{{1}}而不会脱离窗口。所以即使我愿意也不会收到活动。如果你有见解,能不能详细说明一下?

提前致谢

3 个答案:

答案 0 :(得分:5)

您可以在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();
   }
}

如果您想确保将自定义视图添加到您想要的正确视图组

@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 :(得分:2)

在我的意见中,你想要这样;

CreateViews;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);



    final LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);

    layout.setOnHierarchyChangeListener(new OnHierarchyChangeListener() {

        @Override
        public void onChildViewRemoved(View parent, View child) {
            Log.e("View","removed");
            if(child instanceof CustomButton){
                CustomButton button = (CustomButton)child;
                button.addListener();
            }
        }

        @Override
        public void onChildViewAdded(View parent, View child) {
            Log.e("View","added");
            if(child instanceof CustomButton){
                CustomButton button = (CustomButton)child;
                button.addListener();
            }
        }
    });

    for(int i = 0; i < 10; ++i){
        CustomButton view = new CustomButton(this);
        view.setText("Button "+i);
        layout.addView(view, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

        view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                layout.removeViewAt(layout.getChildCount()-1);
            }
        });

    }

    setContentView(layout);

}

监听器;

public interface OnAddedListener {

    public void addListener();

}

CustomButton类;

public class CustomButton extends Button implements OnAddedListener{

    public CustomButton(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public CustomButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public CustomButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void addListener() {
        Log.e("","In button add listener");
    }



}

答案 2 :(得分:1)

根据Android源代码,除非首先在其父级上调用removeView(),否则视图不能移动到另一个布局;如果您查看removeView()的代码,它将调用{ {1}},依次调用removeViewInternal()的重载,在this行调用removeViewInternal(),这基于this行调用的Android源代码view.dispatchDetachedFromWindow()。然后使用onDetachedFromWindow()添加视图,该视图以相同的方式调用addView()