【问题标题】:When is the correct moment to call getWidth() / getHeight() on a View?在 View 上调用 getWidth() / getHeight() 的正确时机是什么时候?
【发布时间】:2013-11-27 14:59:24
【问题描述】:

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

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

子视图必须具有 200dp 的固定宽度。因此,在将 SubViews 动态添加到 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()和已经添加的SubViews的getWidth()return 0,因此,检查是否有足够的空间会出错。

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

    @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?一般来说,什么时候是正确的时刻(哪个回调方法,根据 Activity 生命周期)对于要调用的 View 的 getWidth()getHeight(),确保它们不会返回0?

到目前为止我所尝试的:

  • 在 Fragments onActivityCreated(...) 中调用我的 RowView 的 addSubView(...) --> 不起作用
  • 在 RowViwes onSizeChanged(...) 方法中连接到数据库,那里的所有addSubView(...) --> 不起作用
  • 按照上面代码中的说明进行操作,但使用延迟 500 毫秒的处理程序 --> 可以工作,因为 UI 已呈现,但对我来说不是一个合适的解决方案

【问题讨论】:

  • 请告诉我该问题的答案向我解释什么时候在视图上调用 getWidth() 的正确时机,根据例如活动生命周期?
  • 从该页面应该清楚,没有任何与活动生命周期相关的内容可以确定适合阅读布局,同时在该页面上使用onDraw() (不是生命周期的一部分)是推荐的。在这种可能性和您建议的计时器(我之前成功使用过)之间,您已经用尽了没有进行操作系统级别更改的可用时间。

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


【解决方案1】:

您尝试做的不是工作,因为在您想知道元素宽度的那一刻,布局还没有完成。有两种解决方案。第一个是确定布局的实际宽度,这在您的情况下很容易,因为它是实际的屏幕宽度:

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

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

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

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

int maxViewsToAdd = (int) width/viewWidth;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多