Ответ 1
Я начинаю сомневаться, что в контексте PopupWindow
, что -2, -2 на самом деле означает WRAP_CONTENT
, скорее я считаю, что его просто интерпретирует его как width = -2 height = -2
Это из источника Android
public PopupWindow(View contentView, int width, int height, boolean focusable) {
if (contentView != null) {
mContext = contentView.getContext();
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
}
setContentView(contentView);
setWidth(width);
setHeight(height);
setFocusable(focusable);
}
где setWidth(int width)
- просто простая mWidth = width;
Я думаю, что вместо этого вы ищете setWindowLayoutMode (int widthSpec, int heightSpec) метод. Вот где вы должны пройти в WRAP_CONTENT
Если все остальное не работает, измерьте ширину и высоту TextView
, а затем используйте setWidth
и setHeight
, как ожидалось.
Edit
Просто попробовал это для себя и добавил эту строку кода, чтобы заставить ее работать
// -2 means WRAP_CONTENT THIS TRIGGERS THE PROBLEM
popup = new PopupWindow(getPopupContent(), 200, 100);
popup.setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
// When you specify the dimensions everything goes fine
//popup = new PopupWindow(getPopupContent(), 200, 100);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
Я оставил оригинальные комментарии там, чтобы вы могли сами увидеть, куда все должно идти.
Изменить 2: Хорошо, поэтому я взял ваш код, который вы разместили, и дословно пробовал его на своем устройстве, и вы были правы, это не сработало, потому что, когда Android определяет, какие представления на макет вставлять, он полагается на ширину и высоту, которые вы предоставили, Это означает, что с тех пор, как вы используете 0 и 0 в качестве вашей ширины и высоты, Android придет и скажет: "О, посмотри, в поле есть только поле" 0 на 0 ", чтобы я мог отображать его как всплывающее окно под контентом". Это не то, что нужно! Дело в том, что вы знаете, что ящик будет больше, чем это, поэтому давайте начнем вводить разные цифры и видеть результаты, которые приходят от него.
popup = new PopupWindow(getPopupContent(), 1, 1);
Теперь, когда я иду и нажимаю на нижний ящик, заметьте, что он прыгает выше. (См. Снимок экрана). Потому что Android ЗНАЕТ, что ширина и высота равны 1 (как я установил в конструкторе) и что доступное пространство экрана под элементом списка равно 0. Ну, если там не хватает места для его отображения, должно быть выше!
Но подождите! Что, если в моем текущем примере строка добавляет больше контента каждый раз? Ну, вот где вещи становятся интересными. На следующем скриншоте вы видите, что всплывающее окно, хотя оно должно отображаться, так как оно имеет длину 6 строк, скорее отображается внизу! О, дерьмо, верно! Это потому, что оно измеряется против 1 1
, который я использовал в конструкторе. Ну, а какие-то решения для этого?
Решение: мой предпочтительный способ состоял бы в том, чтобы угадать, какова средняя максимальная высота TextView
, а затем просто бросить в общем общем количестве.
popup = new PopupWindow(getPopupContent(), 300, 300); //just guessing it won't get bigger than that
Решение второе: это более правильно, но вы жертвуете небольшой скоростью, чтобы сделать это. Использование класса Paint
для определения размера текстового содержимого и передачи его в setWidth()
и setHeight()
перед отображением всплывающего окна. Я пошел вперед и построил почти полное решение, но я не измерял его заполнение и прочее (см. Комментарий).
private int maxWidth;
private int maxHeight;
private Paint p = new Paint();
private Rect bounds = new Rect();
private View getPopupContent() {
maxWidth = 0;
maxHeight = 0;
TextView popupContent = new TextView(this);
popupContent.setText(popupText += "\n" + DEMO);
popupContent.setTextColor(Color.parseColor("#5000ae"));
popupContent.setBackgroundColor(Color.parseColor("#ff00ff"));
popupContent.setPadding(10, 20, 20, 10);
//the measure can only work line by line so I split it up by line
String[] temp = popupText.split("\n");
for (String s : temp){
//measure each line of string and get its width and height
p.getTextBounds(s, 0, s.length(), bounds);
//keep a running total of the longest width
maxWidth = (bounds.width() > maxWidth) ? bounds.width() : maxWidth;
//add up each of the heights
maxHeight += bounds.height();
}
//also take in account the padding too... if you REALLY want it to be completely robust
//probably adding another 20 or 30 to the maxHeight should be good
return popupContent;
}
И затем в onClick()
я добавил эти две строки
popup.setHeight(maxHeight);
popup.setWidth(maxWidth);