avalancha
avalancha

Reputation: 1774

Notification on View added to parent?

When I build a View in Android dynamically I have to add it to a "parent" ViewGroup by calling

myLinearLayout.addView(myView);

I know that I can supervise the ViewGroup for any children to be added via the excellent onHierarchyChangeListener, but in my case I need the feedback in the View itself. Therefore my question is:

Is there something like a View.onAddedToParent() callback or a listener that I can build on?

To make things very clear: I want the view to handle everything on its own, I am aware of the fact that I could catch the event in the "parent" and then notify the view about things, but this is not desired here. I can only alter the view

Edit: I just found onAttachStateChangeListener and it would seem to work for most situations, but I'm wondering if this is really the correct solution. I'm thinking a View might just as well be passed on from one ViewGroup to another without being detached from the window. So I would not receive an event even though I want to. Could you please elaborate on this if you have insight?

Thanks in advance

Upvotes: 5

Views: 5536

Answers (3)

kyay10
kyay10

Reputation: 942

According to the Android source code, a view can't be moved to another layout unless removeView() is called first on its parent, and if you look at the code of removeView(), it calls removeViewInternal(), which in turn calls an overload of removeViewInternal(), which, on this line calls view.dispatchDetachedFromWindow(), which, based on the Android source code on this line calls onDetachedFromWindow(). Then the view gets added using addView(), which calls onAttachedToWindow() in the same way.

Upvotes: 3

nurisezgin
nurisezgin

Reputation: 1570

In my opion you want like this;

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

}

Listener;

public interface OnAddedListener {

    public void addListener();

}

CustomButton class;

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



}

Upvotes: 2

Diego Palomar
Diego Palomar

Reputation: 7061

You can create custom view and do your stuff in its 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();
   }
}

If you want to ensure that your customview added to correct viewgroup which you want

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

}

Upvotes: 5

Related Questions