2013-10-09 3 views
14

У меня ширина изображения ImageView 0. Ниже приведен код.ImageView.getWidth() возвращает 0

XML файл:

<ImageView 
     android:id="@+id/img" 
     android:layout_width="200dp" 
     android:layout_height="200dp" /> 

активность:

@Override 
protected void onResume() { 
    super.onResume(); 
    ImageView img = (ImageView) findViewById(R.id.img); 
    Log.d(TAG, "width : " + img.getWidth()); 
} 

Я не хочу использовать ниже код, как мне нужно, чтобы поместить этот код в очень многих местах.

ViewTreeObserver vto = img.getViewTreeObserver(); 
    vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
     public boolean onPreDraw() { 
      ImageView img = (ImageView) findViewById(R.id.img); 
        Log.d(TAG, "width : " + img.getWidth()); 
      return true; 
     } 
    }); 

Мой обходной путь: я на самом деле позже не нужно, чтобы добавить этот код в деятельности. Я добавил его в класс non-activity и вместо ширины ImageView использовал ширину изображения Bitmap, и теперь у меня нет этой проблемы.

+0

в onResume, экран еще не выложен, все компоненты по-прежнему 0x0. Возьмите вызов getMeasuredWidth или вызовите его после завершения макета – njzk2

+1

@ njzk2 getMeasuredWidth() также возвращает 0. – Geek

ответ

32

Где вы звоните getWidth() и getHeight() на ImageView? Если вы звоните с onCreate() в действии, это не сработает. Вам нужно подождать, пока окно активности не будет подключено, а затем вызовите getWidth() and getHeight() на ImageView. Вы можете попробовать позвонить getWidth() and getHeight() с onWindowFocusChanged() метод вашей деятельности.

вызов на onWindowFocusChanged как этот путь

public void onWindowFocusChanged(boolean hasFocus) { 
    // TODO Auto-generated method stub 
    super.onWindowFocusChanged(hasFocus); 
    if (hasFocus) { 
     ImageView img = (ImageView) findViewById(R.id.img); 
     Log.d(TAG, "width : " + img.getWidth()); 
    } 

    } 
+0

Когда он называется? – Geek

+0

после запуска метод вызывается ... –

+1

Не вызывается onResume после onStart? Я поместил свой код в onResume. – Geek

7

Поскольку у вас уже есть «фиксированный» ширина ImageView из 200dp почему вы не просто положить его в dimens.xml

<dimen name="image_width">200dp</dimen> 

, а затем просто

int width = (int) getResources().getDimension(R.dimen.image_Width) 
+0

Это просто пример. Я использую этот код для manyImageViews, и не у всех есть размер исправления. Некоторые используют wrap_content. – Geek

+1

getWidth и getHeight могут отличаться в зависимости от разрешения устройства для одних и тех же изображений, поэтому вы не можете так использовать таким образом –

+0

Хорошо ... и вы голосуете за это? Вы должны использовать лучшие примеры: P @SanketKachhela, который не соответствует действительности, уменьшает ресурс, заботится об этом (если мы говорим о предопределенных размерах (например, о том, что используется в исходном вопросе) – linakis

2

ну, я нашел много вопросов, связанных с этим, повторяющихся к этому вопросу, и большинство ответов не подходят для моего дела.

Я придумал решение, которое может поместиться для вас, как и для меня. Просто я создал пользовательский ImageView и добавил новый обратный вызов OnSizeChangedCallback, который вызывается всякий раз, когда размер представления изменяется на ненулевые значения.

Вот пример кода из моих собственных:

public class AvatarImageView extends ImageView{ 

    private OnImageViewSizeChanged sizeCallback = null; 

    public AvatarImageView(Context context) { 
     super(context); 
    } 

    public AvatarImageView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public AvatarImageView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     if (w == 0 || h == 0) { 
      return; 
     } 
     else{ 
      if(sizeCallback != null) 
       sizeCallback.invoke(this, w, h); 
     } 

    } 

    public void setOnImageViewSizeChanged(OnImageViewSizeChanged _callback){ 
     this.sizeCallback = _callback; 

     if (getWidth() != 0 && getHeight() != 0) { 
      _callback.invoke(this, getWidth(), getHeight()); 
     } 
    } 

    public interface OnImageViewSizeChanged{ 
     public void invoke(ImageView v, int w, int h); 
    } 
} 

и вы можете просто использовать его следующим образом:

final AvatarImageView avatarIcon = (AvatarImageView) findViewById(R.id.avatarImg); 
avatarIcon.setOnImageViewSizeChanged(new AvatarImageView.OnImageViewSizeChanged() { 
    @Override 
    public void invoke(ImageView v, final int w, final int h) { 
      // Do whatever you want with w and h which are non zero values ... 
    } 
}); 

связанные вопросы:

  1. views-getwidth-and-getheight-returning-0
  2. android-imageview-return-getwidth-getheight-zero
  3. android-get-width-returns-0
Смежные вопросы