`

Android getWidth和getMeasuredWidth的正解

阅读更多
一。也許很多童鞋對getWidth()和getMeasuredWidth()的用法有很多的不解,這兩者之間有什麼樣的不同呢,網上也有各種不同的版本,但大多數都大同小異,從這個地方Ctrl+C,到另一個地方Ctrl+V,沒有把問題說透,也有一部分文章誤導了大家對這兩個方法的認識,我也是深受其害。這裡先糾正下面的一個版本的說法,Baidu上一搜一大堆的,可惜這種說法是錯的,所以希望大家就不要再盲目的轉載到你的空間裡:
                      getWidth得到是某个view的实际尺寸.
                      getMeasuredWidth是得到某view想要在parent view里面占的大小.
想必你也見過這樣的解釋,聽起來這樣的解釋也似雲裡霧裡,沒有把問題點透。

二。好了,錯誤的版本就不過多說了,下面對這兩個方法做一下正解,首先大家應先知道以下幾點:
1. 在一個類初始化時,即在構造函數當中我們是得不到View的實際大小的。感興趣的朋友可以試一下,getWidth()和getMeasuredWidth()得到的結果都是0.但是我們可以從onDraw()方法裡面得到控件的大小。
2. 這兩個方法所得到的結果的單位是像素即pixel.
對兩個方法做介紹:
getWidth(): 得到的是view在父Layout中佈局好後的寬度值,如果沒有父佈局,那麼默認的父佈局是整個屏幕。也許不好理解。通過一個例子來說明一下。
例1 :
public class Test extends Activity {
 private LinearLayout mBackgroundLayout;
 private TextViewTest mTextViewTest;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  mBackgroundLayout = new MyLayout(this);
  mBackgroundLayout.setLayoutParams(new LinearLayout.LayoutParams(
    LinearLayout.LayoutParams.FILL_PARENT,
    LinearLayout.LayoutParams.FILL_PARENT));

  mTextViewTest = new TextViewTest(this);

  mBackgroundLayout.addView(mTextViewTest);
  setContentView(mBackgroundLayout);
 }
 public class MyLayout extends LinearLayout{

  public MyLayout(Context context) {
   super(context);
   // TODO Auto-generated constructor stub
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
   // TODO Auto-generated method stub
   super.onLayout(changed, l, t, r, b);
   Log.i("Tag", "--------------");
   View mView=getChildAt(0);
   mView.measure(0, 0);
  }
  
 }
 public class TextViewTest extends TextView {
  public TextViewTest(Context context) {
   super(context);
   // TODO Auto-generated constructor stub
   setText("test test ");
  }
  
  @Override
   protected void onDraw(Canvas canvas) {
   // TODO Auto-generated method stub
   super.onDraw(canvas);
   // measure(0, 0);
   Log.i("Tag", "width: " + getWidth() + ",height: " + getHeight());
   Log.i("Tag", "MeasuredWidth: " + getMeasuredWidth()
     + ",MeasuredHeight: " + getMeasuredHeight());
   }

 }
}

這裡是在LinearLayout裡添加一個TextView控件,如果此時要得到對TextView獲取getWidth(),那麼是在TextView添加到Layout後再去獲取值,並不單單的是對TextView本身寬度的獲取。
getMeasuredWidth():先看一下API裡面怎麼說的
The width of this view as measured in the most recent call to measure(). This should be used during measurement and layout calculations only.
得到的是在最近一次調用measure()方法測量後得到的view的寬度,它僅僅用在測量和layout的計算中。
所以此方法得到的是view的內容佔據的實際寬度。
你如果想從一個最簡單的例子中的到它們的不同,下面將對上面的例子做一下修改:
public class Test extends Activity {
 private TextViewTest mTextViewTest;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  mTextViewTest = new TextViewTest(this);
  setContentView(mTextViewTest);
 }

 public class TextViewTest extends TextView {
  public TextViewTest(Context context) {
   super(context);
   // TODO Auto-generated constructor stub
   setText("test test ");
  }

  @Override
  protected void onDraw(Canvas canvas) {
   // TODO Auto-generated method stub
   super.onDraw(canvas);
   measure(0, 0);
   Log.i("Tag", "width: " + getWidth() + ",height: " + getHeight());
   Log.i("Tag", "MeasuredWidth: " + getMeasuredWidth()
     + ",MeasuredHeight: " + getMeasuredHeight());
  }
 }
}

總結(正解):
  getWidth(): View在設定好佈局後整個View的寬度。
  getMeasuredWidth(): 對View上的內容進行測量後得到的View內容佔據的寬度,前提是你必須在父佈局的onLayout()方法或者此View的onDraw()方法裡調用measure(0,0);(measure 參數的值你可以自己定義),否則你得到的結果和getWidth()得到的結果一樣。
       也許我組織的不是很好,大家有什麼不清楚的地方再給我留言。關於這兩個方法的區別就是看你有沒有用measure()方法,當然measure()的位置也是很重要的。
三.請尊重原創,轉載請註明這是http://hi.baidu.com/ljlkings/home的空間。
分享到:
评论
2 楼 gundumw100 2011-12-02  
烧伤的火柴 写道
可是想问你一下如何得到view在屏幕上的位置
getLocationOnScreen  不好用

getRawX()
1 楼 烧伤的火柴 2011-12-02  
可是想问你一下如何得到view在屏幕上的位置
getLocationOnScreen  不好用

相关推荐

    爱华对view的理解之Android相近且易混淆的13种属性.pdf

    7. **Android 中 getWidth 和 getMeasuredWidth 的区别** - `getWidth()` 返回当前View的实际宽度,包括Padding,但在测量阶段可能返回0。 - `getMeasuredWidth()` 返回测量阶段确定的View宽度,包含了...

    android实例竖着的seekbar

    在Android开发中,SeekBar是一种常用的用户界面组件,它允许用户通过滑动条来选择一个介于最小值和最大值之间的数值。通常情况下,SeekBar是水平排列的,但有时根据设计需求,我们可能需要创建一个垂直方向的SeekBar...

    Android截屏截图的几种方法总结

    Android截屏截图的几种方法总结 Android截屏截图是 Android 开发中常见的需求, Android 截屏... Android 截屏截图有多种方法,每种方法都有其特点和应用场景。在实际开发中,您可以根据实际需求选择合适的截屏方法。

    Android-可以指定圆角的ViewGroup

    在Android开发中,创建具有指定圆角的ViewGroup是一个常见的需求,这可以帮助开发者设计出更加美观和具有现代感的用户界面。"Android-可以指定圆角的ViewGroup"这个主题聚焦于如何在Android应用中实现自定义的布局,...

    Android截屏(可截取不可见的部分)

    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); ``` 2. **准备Canvas**:创建一个Canvas对象,它将用于绘制Bitmap。 ```java Canvas canvas = new Canvas...

    android 带文字的图片按钮的实现

    int x = (this.getMeasuredWidth() - bitmap.getWidth()) >> 1; int y = 0; canvas.drawBitmap(bitmap, x, y, null); // 让文字在底部显示 canvas.translate(0, (this.getMeasuredHeight() >> 1) - (int) this...

    Android应用源码之垂直SeekBar(拖动条).zip

    在Android开发中,SeekBar是一个非常常见的控件,它允许用户通过滑动来选择一个介于最小值和最大值之间的值。然而,默认的SeekBar是水平布局的,而在某些设计需求下,我们可能需要创建一个垂直方向的SeekBar。这篇...

    android 自定义view流式布局

    在Android开发中,自定义View是一项重要的技能,它允许开发者根据特定需求创建独特且复杂的UI组件。本篇文章将深入探讨如何实现一个自定义的“流式布局”(Flow Layout),这是一种能够自动调整子视图(child views...

    Android imageview添加水印

    int x = getMeasuredWidth() - watermarkBitmap.getWidth(); // 水印图片的X坐标 int y = getMeasuredHeight() - watermarkBitmap.getHeight(); // 水印图片的Y坐标 canvas.drawBitmap(watermarkBitmap, x, y, null...

    android获取控件宽高

    在布局完成后,可以通过`getMeasuredWidth()`和`getMeasuredHeight()`获取测量尺寸。但是,如果需要获取实际尺寸,通常需要在`onDraw()`方法或者`onSizeChanged()`方法中进行。例如: ```java @Override ...

    Android自定义滑动开关

    总之,自定义Android滑动开关是一个涉及UI绘制、触摸事件处理和状态管理的过程。通过这种方式,开发者可以创造出符合项目需求的独特组件,提高应用程序的用户体验。提供的资源链接提供了更详细的实现步骤和演示,...

    android搜索热词(热门标签)流式布局的实现

    在Android应用开发中,流式布局(FlowLayout)是一种常见的布局方式,它允许子视图根据屏幕宽度自动换行,类似于网页中的布局模式。在这种布局中,元素会从左到右排列,当一行填满后,元素会自动转到下一行继续排列...

    android自定义控件自动换行效果实现

    在Android开发中,自定义控件是提升应用用户体验和界面设计独特性的重要手段。本教程将探讨如何实现一个自定义控件,它具有自动换行的效果,使得在有限的屏幕空间内,元素能够整齐地排列成多行。参考链接为:。 ...

    Android自定义组件之自动换行View

    if (i == 0 || currentLineWidth + child.getMeasuredWidth() > getWidth()) { left = 0; top += previousChildHeight; } child.layout(left, top, left + child.getMeasuredWidth(), top + child....

    Android流式布局简单实现

    总结,Android流式布局的实现主要涉及对ViewGroup的`onMeasure()`和`onLayout()`方法的重写。通过这种方式,我们可以创建出高度自适应且布局灵活的应用界面,尤其适用于展示大量未知数量的元素,如标签、卡片等。`...

    Android-实现当item的宽度小于RecyclerView的宽度时候则居中显示

    int offset = (getWidth() - child.getMeasuredWidth()) / 2; // 设置新的left margin,使得item居中 layoutParams.leftMargin = -offset; child.setLayoutParams(layoutParams); } } } ``` 在使用这个自定义...

    android 圆形imageview实现 带自定定义大小

    例如,可以添加一个`android:layout_width`和`android:layout_height`,然后在onMeasure()方法中处理尺寸。 ```java @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super....

Global site tag (gtag.js) - Google Analytics