ImageView.getWidth() возвращает 0

Я получаю imageView width 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, и теперь эта проблема не возникает.

Ответы

Ответ 1

Где вы вызываете 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());
     }

    }

Ответ 2

Поскольку у вас уже есть "фиксированная" ширина imageView 200dp, почему бы вам просто не поместить его в dimens.xml

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

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

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

Ответ 3

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

Я придумал решение, которое может поместиться для вас, как и для меня. Просто я создал пользовательский 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 ...
    }
});

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