何时是在视图上调用getWidth()/ getHeight()的正确时刻?

时间:2013-11-27 14:59:24

标签: android android-view android-custom-view android-lifecycle

编辑 - >请问,这是一个问题为什么getWidth()/ getHeight()返回零。

我在Activity中有一个Fragment。 我动态地将SubViews(红色)添加到水平方向的LinearLayout(RowView,蓝色),这是Fragment(绿色)的子级。在运行时确定将多少个子视图(SubViews)添加到LinearLayout中。

enter image description here

SubView必须具有200dp的固定宽度。因此,当动态地将子视图添加到Linearlayout时,我想检查是否有足够的空间用于另一个SubView,或者是否需要启动新的Row。 RowView的宽度应该是可变的,并且不一定等于屏幕大小。

为了检查是否有足够的空间,我只是看看所有SubView的组合宽度是否小于Linearlayout的宽度 - 一个SubView的宽度。在我的自定义LinearLayout(RowView)中,如下所示:

public void addSubView(SubView v) {

        int childcount = getChildCount();
        int totalChildWidth = 0;

        for(int i = 0; i < childcount; i++) {
            totalChildWidth += getChildAt(i).getWidth(); 
        }

        if(totalChildWidth < getWidth() - 200) { // there is space left in this row
            addView(v);
        } 
    }

问题就在于,LinearLayout的getWidth()和已添加的SubView getWidth()返回0 ,因此检查是否有足够的空间出错

原因是我在视图(UI)尚未在屏幕上呈现时调用getWi'dtdh(),所以我的问题是什么时候到了调用我的addSubView()方法?目前,我在创建片段时调用它,这显然是错误的:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment, container, false);

        RowView row = (RowView) v.findViewById(R.id.rowView);
        ArrayList<SubView> subViews = DBManager.getSubViewList(); // connects to a database and returns all available subviews

        for(int i = 0; i < subViews.size(); i++) {
            row.addSubView(subViews.get(i));
        }

        return v;
    }

那么在哪里调用我的addSubView(...)方法,确保其中的getWidth()不会返回0?通常,何时是正确的时刻(根据活动生命周期的回调方法),要调用视图的getWidth()getHeight(),确保他们不会返回0?

到目前为止我尝试过:

  • 在片段addSubView(...)中调用我的RowView的onActivityCreated(...) - &gt;不起作用
  • 连接到RowViwes onSizeChanged(...)方法内的数据库,以及那里的所有addSubView(...) - &gt;不起作用
  • 按照上面的代码中所述进行操作,但使用延迟500ms的处理程序 - &gt;工作,因为UI被渲染,但对我来说不是一个合适的解决方案

1 个答案:

答案 0 :(得分:1)

您尝试执行的操作无法正常工作,因为在您想要了解元素的宽度时,布局尚未完成。有两种解决方案。第一个是确定布局的实际宽度,这在您的情况下很容易,因为它是实际的屏幕宽度:

int width = getActivity().getResources().getDisplayMetrics().widthPixels

通过将200dp转换为像素,使用此值来确定您可以在一行中添加的子视图的数量:

int viewWidth = (int) (200 * (getActivity().getResources().getDisplayMetrics().densityDpi / 160f));

然后您可以计算一行的最大视图数:

int maxViewsToAdd = (int) width/viewWidth;

另一个解决方案是globalLayoutListener,您可以找到说明here。但这似乎并不适用于所有情况。