user68621 user68621 - 4 months ago 15
Android Question

Adding a view second time is not visible on Android

I have a class called OverlayBuild, with the purpose of drawing "things" on views, but for some reason I experienced a problem that seemed simple, but still costs me a lot of time. The problem is that when the class is used for the second (and 3rd, 4th etc.) the drawing/view is not added to its parent view, or not visible at least!

I tried simplifying the class to identify the cause of the error, but it still occurs.

So here is my code for the OverlayBuild class first:

public class OverlayBuild {

private String tag;
private Context context;
private ViewGroup container;
private RelativeLayout overlay;
public static boolean layoutLoaded;
private int backgroundWidth = 1500;
private int backgroundHeight = 1500;
private boolean overlayLayoutCompleted;


public OverlayBuild(Context context, ViewGroup container, String tag) {
this.tag = tag;
this.context = context;
this.container = container;
this.overlay = new RelativeLayout(context);
layoutLoaded = false;
}

public OverlayBuild setLayoutListener(final LayoutListener layoutListener) {
container.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (!layoutLoaded) {
layoutListener.layoutPrepared(container);
layoutLoaded = true;
}
}
});

return this;
}
public OverlayBuild setBackgroundDimens(int width, int height) {
this.backgroundWidth = width;
this.backgroundHeight = height;
return this;
}

public OverlayBuild hideOverlay(){
if(overlay != null){
overlay.setVisibility(View.GONE);
}
return this;
}


public OverlayBuild commit() {
View view = getViewByTag(tag);
if (view == null) {
container.addView(overlay);
overlayLayoutCompleted = true;
overlay.setTag(tag);

overlay.bringToFront();
overlay.setVisibility(View.VISIBLE);

container.setBackgroundResource(R.color.red);
overlay.setBackgroundResource(R.color.blue_mid);
}


return this;
}


private View getViewByTag(String tag) {
return container.findViewWithTag(tag);
}

public interface LayoutListener {
void layoutPrepared(ViewGroup view);
}


And here is the method where I use the class to "draw":

public static void showEmptyState(final Context context, final Button createAgentBtn, final ViewGroup parentView, final String tag) {

final OverlayBuild builder = new OverlayBuild(context, parentView, tag);
builder.setLayoutListener(new OverlayBuild.LayoutListener() {
@Override
public void layoutPrepared(ViewGroup view) {
final ViewGroup.MarginLayoutParams btnParams = (ViewGroup.MarginLayoutParams) createAgentBtn.getLayoutParams();

final int parentWidth = parentView.getWidth();
final int parentHeight = parentView.getHeight();

builder.setBackgroundDimens(parentWidth,parentHeight)
.commit();
}
});
}


As you can see in the method called "commit()", I am setting some background colors (for testing purposes). In conclusion I can see that the color is visible on the screen the first time, but not the next time etc.

I have debugged it (a lot!) and can verify that it reaches all of the places in the code that it should.

I really hope someone can help me out. Any help will be greatly appreciated.

Answer

I found the answer myself. By changing the field:

public static boolean layoutLoaded

to "non-static":

public boolean layoutLoaded

The problem was solved, as there was only a single instance of this boolean, which caused confusion of the state when called the second time.