Android-当宽度已知时,在自定义viewgroup/relativelayout中添加视图的最佳位置

Android-当宽度已知时,在自定义viewgroup/relativelayout中添加视图的最佳位置,android,android-layout,width,android-relativelayout,android-custom-view,Android,Android Layout,Width,Android Relativelayout,Android Custom View,我目前正在优化包含许多嵌套视图的复杂视图。因此,我创建了一个扩展relativelayout类的自定义布局。 基于类外的数据集,我进一步构建了带有childs的视图。 子建筑在自定义布局中完成。我让它工作起来了,性能提高了很多。但在创建和添加孩子之前,我需要知道视图的宽度。 有几种方法可以获得视图的宽度: 1添加全局布局侦听器 public void init(){ getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObs

我目前正在优化包含许多嵌套视图的复杂视图。因此,我创建了一个扩展relativelayout类的自定义布局。 基于类外的数据集,我进一步构建了带有childs的视图。 子建筑在自定义布局中完成。我让它工作起来了,性能提高了很多。但在创建和添加孩子之前,我需要知道视图的宽度。 有几种方法可以获得视图的宽度:

1添加全局布局侦听器

public void init(){

 getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            //width is known -> create child views
        }
    });
 }
此解决方案并不总是触发事件。例如,当视图位于片段内部并从backstack状态恢复时。此外,在触发此事件之前,似乎还有100到500毫秒的延迟

  • 未经测量

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    w = MeasureSpec.getSize(widthMeasureSpec);
    h = MeasureSpec.getSize(heightMeasureSpec);
    
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    setMeasuredDimension(w, h);
    
    post(new Runnable() {
        @Override
        public void run() {
            //width is known -> create child views  
            MyCustomViewGroup.this.postInvalidate();
        }
    });
    
    }
    
  • 这里的困难在于在onmeasure中添加视图将导致再次调用onmeasure。结果就是没完没了的循环。防止这种情况的逻辑。不知道怎么做

    3在onLayout中添加视图

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        //width is known -> create child views
    }
    
    各种意外的布局问题。不尊重布局参数并表现出怪异行为的视图。我不知道该怎么解决

  • 黑客定时器实现

    private Handler ha = new Handler();
    private Runnable r;
    
    public void init() {
        if (w > 0) {
            //width is known ->create childs
            return;
        }
        r = new Runnable() {
    
            private long time = 0;
    
            @Override
            public void run() {
                Log.d(TAG, "run");
                if (w > 0) {
                    //width is known ->create childs
                } else {
                    init(); //width is not known -> check later
                }
            }
        };
        ha.postDelayed(r, 5);
    }
    
  • 具有讽刺意味的是,最后一个解决方案最适合我。 我知道这是一个地狱般的恶作剧。
    有人知道其他选择吗?或者可以给我一些提示。

    2
    ,但主要是
    4
    :你可以使用异步任务:尝试添加视图InLayout?但老实说,我真的不知道为什么在添加子视图时需要父视图大小,这真的很奇怪……我需要知道大小,因为我想手动布局视图。我知道我可以通过线性布局或相对布局实现同样的效果。我只需要手动布局每个视图,这样我就可以加快整个视图的速度。@Gillishasnoot这样做是在onLayout方法中,迭代每个子视图并在其上调用布局(l,t,r,b)