Method to override when layout is destroyed in Android
Asked Answered
H

3

45

I have a custom component which extends LinearLayout, I need to execute certain statements when Layout is destroyed or removed. (or about to be removed)

One way is to check for onPause() or onDestroy() of an activity and call methods of the custom component. But I want to remove that overhead from the activity. So that custom component itself can handle when layout is detached. But I dint find the suitable method to override (to detect the event) when layout is removed. Is there a way to handle this, or we need to use onPause() and onResume() method of activity ?

Hamann answered 25/1, 2012 at 10:44 Comment(0)
D
6

It is dangerous to rely on the "destruction" of a layout to execute statements, as you're not directly in control of when that happens. The accepted way and good practice is to use the activity's lifecycle for that.

But if you really want to tie your component to that lifecycle, I suggest your component implements an interface (something like Removable), and do something like that in your base activity classe (that all your activities extend):

protected Set<Removable> myRemovableItems = new HashSet<Removable>();

@Override
public void onPause() {
    super.onPause();
    for (Removable removable : myRemovableItems) {
        removable.remove();
    }
}

The interface:

public interface Removable {
    void remove();
}

Then each time you add one of your custom component from an activity, you add the component to the internal set of Removable of the activity, and its remove method will be automatically called each time the activity is paused.

That would allow you to specify what to do when onPause is called within the component itself. But it wouldn't ensure it's automatically called, for that you'll have to do it in the activity.

Note: you can use onStop instead of onPause depending on when you want the removal to occur.

Dislocation answered 25/1, 2012 at 11:1 Comment(1)
Sorry, while this advice may be generally okay in some abstract sense when applied to data objects, it is misleading and incorrect in just about every way imaginable as general advice. If you can couple your lifecycle to the attach/detach events, then that is exactly where your logic belongs as the OP suggests. Having the activity deal with things only makes sense if you need a different lifecycle for your objects than you get with attach/detach. Plus, Activity exposes callbacks from from the WindowManager for when the root view is attached/detached which you failed to mention.Newspaper
T
86

I had success overriding the onAttachedToWindow() and onDetachedFromWindow() methods:

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    // View is now attached
}

@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    // View is now detached, and about to be destroyed
}
Tradesman answered 24/5, 2013 at 14:52 Comment(3)
Those methods are called when the View is removed from a ViewGroup also? Or only from the Window (such the main activity ContentView) ? As far I read at ViewGroup and View code this is not.Engelbert
This answer is also misleading, "onDetachedFromWindow" is called when using the backbutton, but not when using the homebutton. Using this method the custom component does not get "paused" when the user exits the app using the home-button.Manlike
This answer has some good examples too: https://mcmap.net/q/363629/-can-a-custom-view-know-that-onpause-has-been-calledManlike
D
10

You can have your custom view listen to its own eventss. I suggest using View.OnAttachStateChangeListener and listening to onDetach event.

@Override
void onViewDetachedFromWindow(View v) {
 doCleanup();
}
Dandle answered 25/1, 2012 at 11:26 Comment(2)
On Android 5.0+, when we clean our component at onViewDetachedWindow, view's attributes are null. What could be used instead of onViewDetachedWindow?Pinto
@quick release : may be you are calling 'doCleanup()' after 'super.onDetachedFromWindow();'Marileemarilin
D
6

It is dangerous to rely on the "destruction" of a layout to execute statements, as you're not directly in control of when that happens. The accepted way and good practice is to use the activity's lifecycle for that.

But if you really want to tie your component to that lifecycle, I suggest your component implements an interface (something like Removable), and do something like that in your base activity classe (that all your activities extend):

protected Set<Removable> myRemovableItems = new HashSet<Removable>();

@Override
public void onPause() {
    super.onPause();
    for (Removable removable : myRemovableItems) {
        removable.remove();
    }
}

The interface:

public interface Removable {
    void remove();
}

Then each time you add one of your custom component from an activity, you add the component to the internal set of Removable of the activity, and its remove method will be automatically called each time the activity is paused.

That would allow you to specify what to do when onPause is called within the component itself. But it wouldn't ensure it's automatically called, for that you'll have to do it in the activity.

Note: you can use onStop instead of onPause depending on when you want the removal to occur.

Dislocation answered 25/1, 2012 at 11:1 Comment(1)
Sorry, while this advice may be generally okay in some abstract sense when applied to data objects, it is misleading and incorrect in just about every way imaginable as general advice. If you can couple your lifecycle to the attach/detach events, then that is exactly where your logic belongs as the OP suggests. Having the activity deal with things only makes sense if you need a different lifecycle for your objects than you get with attach/detach. Plus, Activity exposes callbacks from from the WindowManager for when the root view is attached/detached which you failed to mention.Newspaper

© 2022 - 2024 — McMap. All rights reserved.