Как получить или вычислить ширину/высоту раздутого вида
Как вычислить ширину и высоту раздутого представления, если родителем является PopupWindow, а не ViewGroup? Я не могу использовать LayoutInflator.inflate(int resId, ViewGroup parent, attachToRoot boolean)
, потому что PopupWindow не является ViewGroup, поэтому я использую LayoutInflator.inflate(int resId)
вместо этого, но после этого у меня getWidth() и getHeight() возвращают ноль: (
Мне нужно изменить размер PopupWindow, чтобы он соответствовал представлению, но не может сделать этого, пока в представлении не будет родителя. У меня проблема с курицей и яйцом?
Кстати, представление является подклассом RelativeView, поэтому его вычисление вручную не может быть и речи.
Спасибо заранее,
Барри
Ответы
Ответ 1
Фактически popupWindow поддерживает "обтекание содержимого", поэтому, если вы хотите, чтобы всплывающее окно было точным в вашем представлении, используйте это:
popup = new PopupWindow(context);
popup.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
popup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
- другие параметры -
getWidth()
и getHeight()
возвращает ноль, поскольку вид имеет размер только после рисования на экране. Вы можете попытаться получить значения из LayoutParams
раздутого представления.
Если значение fill_parent
- вы находитесь в ситуации с яйцом.
Если в px
или dp
есть значения, вы можете вручную вычислить размер в пикселях:
Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpSize, context.getResources().getDisplayMetrics()));
Если значение wrap_content
- вы можете использовать метод view.measure()
- все дети и сам вид будут измерены, и вы можете получить view.getMeasuredHeight()
и view.getMeasuredWidth()
.
Ответ 2
Как сказал Jin35, ваша проблема заключалась в том, что ширина и высота вида еще не рассчитаны... размеры не рассчитываются до окончания макета.
Использование фиксированной ширины и высоты из ресурсов измерений (например, из файла values /dimensions.xml) - это один из обходных путей, так как тогда вам не нужно ждать появления представления onMeasure - вы можете получить значение того же измерения ресурс, который вы использовали для представления, которое вас интересует, и используйте его.
Лучшее решение - просто отложить ваши вычисления до тех пор, пока не произойдет onMeasure. Вы можете сделать это, переопределив onMeasure, но более элегантное решение - использовать временный OnGlobalLayoutListener, например так:
View popup = LayoutInflator.inflate(int resId);
if(popup != null) {
// set up an observer that will be called once the listView layout is ready
android.view.ViewTreeObserver viewTreeObserver = listView.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new android.view.ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// This will be called once the layout is finished, prior to displaying.
View popup = findViewById(resId);
if(popup != null) {
int width = popup.getMeasuredWidth();
int height = popup.getMeasuredHeight();
// don't need the listener any more
popup.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
}
}
Ответ 3
Пожалуйста, попробуйте следующее:
Display display = getWindowManager().getDefaultDisplay();
Log.e("", "" + display.getHeight() + " " + display.getWidth());