Search code examples
androidlistviewobserver-pattern

Android - Unregister observer from nested view


I have custom View that extends ListView. This CustomListView has a CustomHeaderView that represents the header of the ListView.

Once I create/inflate the HeaderView I register it to the Grabber class. My problem now is when to unregister this view. When i rotate the device the views are rebuild and the CustomHeaderView is again registered (without being unregistered before).

public class Grabber implements Subject {
    private static ArrayList<Observer> mObservers;
    private int mColor;

    private static Grabber instance;

    private BrandingColorGrabber() {}

    public static Grabber getInstance() {
        if (instance == null) {
            instance = new Grabber();
            mObservers = new ArrayList<>();
        }
        return instance;
    }

    @Override
    public void register(Observer newObserver) {
        mObservers.add(newObserver);
    }

    @Override
    public void unRegister(Observer deleteObserver) {
        mObservers.remove(deleteObserver);
    }

    @Override
    public void notifyObserver() {
        for (Observer currObserver : mObservers) {
            currObserver.update(mBrandingColor);
        }
    }

    public void setColor(int color) {
        this.mColor = color;
        notifyObserver();
    }
}

CustomListView:

public class CustomListView extends ListView {
     ...
    private void initHeader(){
        mCustomHeaderView = new CustomHeaderView(getContext());
        mCustomHeaderView.buildHeader(this, getContext());
        this.addHeaderView(mDrawerHeader);
    }
}

CustomHeaderView:

public class CustomHeaderView extends FrameLayout implements Observer{

 private BrandingColorGrabber brandingColorGrabber; 
 //other vars

public CustomHeaderView(Context context) {
    super(context);
    if(!isInEditMode())
    init(context);
}

public CustomHeaderView(Context context, AttributeSet attrs) {
    super(context, attrs);
    if(!isInEditMode())
        init(context);
}

public CustomHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    if(!isInEditMode())
        init(context);
}

private void init(Context context) {
    grabber = Grabber.getInstance();
    grabber.register(this);
    Log.e("TAG","register header");
}

@Override
public void update(int color) {
    view1.setBackgroundColor(color);
    view2.setBackgroundColor(color);
}

// ---->>>> Where to unregister this view?? where to call grabber.unregister(this); ??

}

I get my view registered, but i don't know where to unregister it. When the decide rotates the view in Registered once again.


Solution

  • Use the lifecycle methods of the activity/fragment to dictate when to unregister the grabber.