第二次添加视图在 Android 上不可见
Adding a view second time is not visible on Android
我有一个叫做OverlayBuild的class,目的是在视图上绘制"things",但由于某种原因,我遇到了一个看似简单的问题,但仍然花费了我很多时间。问题是,当 class 用于第二个(以及第三个、第四个等)时,drawing/view 未添加到其父视图,或者至少不可见!
我尝试简化 class 以确定错误的原因,但它仍然出现。
首先是我的 OverlayBuild class 代码:
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);
}
这是我使用 class 到 "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();
}
});
}
正如您在名为 "commit()" 的方法中看到的那样,我正在设置一些背景颜色(用于测试目的)。总之,我可以看到颜色第一次在屏幕上可见,但下一次就看不到了,等等。
我调试了它(调试了很多次!)并且可以验证它是否到达了代码中它应该到达的所有位置。
我不能确定,但看起来当 commit()
被第二次调用时,视图可能不会 == null
。因此不会再次添加视图,因为您的 addView()
调用在空检查范围内。
您应该在 "Show layout bounds" 设置打开的情况下测试您当前的代码。当视图没有按应有的方式显示时,这对我帮助很大。
转到设置 -> 开发人员选项 -> 打开 "Show layout bounds"。然后,运行将您的代码添加到应该添加第二个视图的位置,并检查您是否可以看到应该添加的第二个叠加视图的布局边界。
还有,你试过不打电话给overlay.bringToFront();
吗?您可能还想尝试在堆栈中跟踪添加的叠加视图,并在 add/remove 时 pushing/popping。
希望对您有所帮助!
我自己找到了答案。通过更改字段:
public static boolean layoutLoaded
到"non-static":
public boolean layoutLoaded
问题已解决,因为这个布尔值只有一个实例,导致第二次调用时状态混乱。
我有一个叫做OverlayBuild的class,目的是在视图上绘制"things",但由于某种原因,我遇到了一个看似简单的问题,但仍然花费了我很多时间。问题是,当 class 用于第二个(以及第三个、第四个等)时,drawing/view 未添加到其父视图,或者至少不可见!
我尝试简化 class 以确定错误的原因,但它仍然出现。
首先是我的 OverlayBuild class 代码:
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);
}
这是我使用 class 到 "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();
}
});
}
正如您在名为 "commit()" 的方法中看到的那样,我正在设置一些背景颜色(用于测试目的)。总之,我可以看到颜色第一次在屏幕上可见,但下一次就看不到了,等等。
我调试了它(调试了很多次!)并且可以验证它是否到达了代码中它应该到达的所有位置。
我不能确定,但看起来当 commit()
被第二次调用时,视图可能不会 == null
。因此不会再次添加视图,因为您的 addView()
调用在空检查范围内。
您应该在 "Show layout bounds" 设置打开的情况下测试您当前的代码。当视图没有按应有的方式显示时,这对我帮助很大。 转到设置 -> 开发人员选项 -> 打开 "Show layout bounds"。然后,运行将您的代码添加到应该添加第二个视图的位置,并检查您是否可以看到应该添加的第二个叠加视图的布局边界。
还有,你试过不打电话给overlay.bringToFront();
吗?您可能还想尝试在堆栈中跟踪添加的叠加视图,并在 add/remove 时 pushing/popping。
希望对您有所帮助!
我自己找到了答案。通过更改字段:
public static boolean layoutLoaded
到"non-static":
public boolean layoutLoaded
问题已解决,因为这个布尔值只有一个实例,导致第二次调用时状态混乱。