GetWidth() и getHeight() всегда возвращает 0. Пользовательский вид - программирование
Подтвердить что ты не робот

GetWidth() и getHeight() всегда возвращает 0. Пользовательский вид

В фрагменте я раздуваю макет с несколькими дочерними представлениями. Мне нужно получить размеры (ширину и высоту) одного из них, который является обычным представлением.

Внутри пользовательского класса просмотра я могу сделать это легко. Но если я попытаюсь сделать это из фрагмента, я всегда получаю 0 как размеры.

 public void onViewCreated(View view, Bundle savedInstanceState) {

    super.onViewCreated(view, savedInstanceState);
    View culoide = view.findViewWithTag(DRAW_AREA_TAG);
    Log.d("event", "culoide is: "+culoide.getWidth()); // always 0
}

Я полагаю, что onViewCreated должен быть правильным местом для его получения, но это хорошо. Я пробовал до super.onViewCreated, в отладке он выглядит так: "findViewWithTag" находит правильное представление, попробовал только поддержку api 7 v4.

Любая помощь?

4b9b3361

Ответ 1

Вы должны подождать до первого измерения и макета, чтобы получить ненулевые значения для getWidth() и getHeight(). Вы можете сделать это с помощью ViewTreeObserver.OnGlobalLayouListener

public void onViewCreated(final View view, Bundle saved) {
    super.onViewCreated(view, saved);
    view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
              view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
              view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }

            // get width and height of the view
        }
    });
}

Ответ 2

Мой предпочтительный метод - добавить OnLayoutChangeListener в представление, которое вы хотите отслеживать

CustomView customView = ...

customView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        // Make changes
    }
});

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

Ответ 3

Вам нужно подождать, пока не будет вызван метод onSizeChanged(), прежде чем вы сможете надежно определить размер представления.

Это называется во время компоновки, когда размер этого представления изменился. Если вы просто добавлены в иерархию представлений, вы вызываетесь с помощью старые значения 0.

Ответ 4

Попробуйте позвонить

culoide.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);

затем попробуйте getWidth() и getHeight()

Ответ 5

Использование ViewTreeObserver.OnGlobalLayoutListener, View.post(Runnable action) или onWindowFocusChanged() не является лучшим решением. Эта статья (примечание: я являюсь автором этой статьи) объясняет, почему и предоставляет рабочее решение, использующее расширение doOnLayout kotlin, основанное на View.OnLayoutChangeListener. Если вы хотите это на Java, в статье есть ссылка на исходный код doOnLayout, он очень прост, и вы можете сделать что-то подобное и в Java.

Ответ 6

Попробуйте проверить onWindowFocusChanged и иметь допустимые значения:

public void onWindowFocusChanged (boolean hasFocus) { }

У меня была аналогичная проблема, когда мне нужно было получить ширину и высоту виджета, и это была функция, в которой я мог гарантировать, что виджет сообщил о правильном размере.