如果我在onResume中为布局调用getMeasuredWidth()或getWidth(),则返回0

时间:2011-08-04 09:26:40

标签: android layout measurement

如果我在onResume中为布局调用getMeasuredWidth()或getWidth(),则返回0。 我认为现在还没有画出来。

另外我认为我需要在绘制布局并调整视图测量值后调用的回调方法中放置getMeasuredWidth()或getWidth()。 我应该使用什么android回调方法?

7 个答案:

答案 0 :(得分:77)

在系统呈现之前,您无法在width上使用height / getMeasuredWidth / getMeasuredHeight / View(通常来自onCreate / onResume)。

对此的简单解决方案是将Runnable发布到布局。 runnable将在View布局后执行。

BoxesLayout = (RelativeLayout) findViewById(R.id.BoxesLinearLayout);
BoxesLayout.post(new Runnable() {
    @Override
    public void run() {
        int w = BoxesLayout.getMeasuredWidth();
        int h = BoxesLayout.getMeasuredHeight();

        ...
    }
});

答案 1 :(得分:36)

This answer说:

使用ViewTreeObserver上的View等待第一个布局。只有在第一个布局后getWidth()/getHeight()/getMeasuredWidth()/getMeasuredHeight()才能正常工作。

ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
  viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
      view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
      viewWidth = mediaGallery.getWidth();
      viewHeight = mediaGallery.getHeight();
    }
  });
}

答案 2 :(得分:5)

您可以在视图中覆盖onLayout();这是由android使用来定位视图所具有的每个子项,因此您可以在super(..)调用后执行您想要执行的操作。

答案 3 :(得分:4)

实际上,如果屏幕上没有显示布局,getWidth()方法会返回0.对我来说似乎有用的是在调用getMeasuredWidth()或getMesuredHeight()之前调用measure()方法。对于测量方法,我使用Layout.WRAP_CONTENT参数来测量布局包含的内容。

希望这有帮助, 米哈伊

答案 4 :(得分:3)

更简单的方法:

view.post(new Runnable() {
    public void run() {
        view.getWidth();
    }
}
);

http://developer.android.com/reference/android/view/View.html#post(java.lang.Runnable)

答案 5 :(得分:1)

解决方案#1: 要动态地执行此操作,您需要一个标记。标签基本上是视图拥有记忆的一种方式。所以将convertView保存在另一个类(MyTag)中。 所以在你的java文件中:

private LayoutInflater layoutInflater;

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    MyTag holder = null;
    View row = convertView;
    if (row == null) {
      //Inflate the view however u can  
String strInflater = Context.LAYOUT_INFLATER_SERVICE;
        layoutInflater = (LayoutInflater) context.getSystemService(strInflater);
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResID, parent, false);
               holder = new MyTag();

            holder.itemName = (TextView) row.findViewById(R.id.example_itemname);
            holder.icon = (ImageView) row.findViewById(R.id.example_image);
            holder.button1 = (Button) row.findViewById(R.id.swipe_button1);
            holder.button2 = (Button) row.findViewById(R.id.swipe_button2);
            holder.button3 = (Button) row.findViewById(R.id.swipe_button3);
            row.setTag(holder);
        } else {
            holder = (MyTag) row.getTag();
        }

        holder.itemName.setText(itemdata.getItemName());
        System.out.println("holder.button3.getMeasuredWidth()= "+ holder.button3.getMeasuredWidth());
        System.out.println("holder.button3.getWidth()= "+ holder.button3.getWidth());

return row;
} //End of getView()


static class MyTag {  //It also works if not static

        TextView itemName;
        ImageView icon;
        Button button1;
        Button button2;
        Button button3;
    }

解决方案#2: 硬编码。预先设定宽度。 在res / values / dimens.xml文件中,包括

<dimen name="your_button_width">50dp</dimen>

然后在res / layout / your_layout.xml文件中,包括

        <Button  
         android:layout_width="@dimen/your_button_width"  />

然后在你的java文件中:

int buttonSize= (int) (context.getResources().getDimension(R.dimen.your_button_width));

答案 6 :(得分:0)

使用以下代码:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
   super.onWindowFocusChanged(hasFocus);
   Log.e("WIDTH",""+view.getWidth());
   Log.e("HEIGHT",""+view.getHeight());
}