Когда правильный момент для вызова getWidth() / getHeight() в представлении?
РЕДАКТИРОВАТЬ -> Пожалуйста, это не вопрос, почему getWidth() / getHeight() возвращают ноль.
У меня есть фрагмент внутри деятельности. Я динамически добавляю SubViews (красный) к LinearLayout (RowView, синий) в горизонтальной ориентации, которая является дочерним элементом фрагмента (зеленый). Сколько из этих дочерних представлений (SubViews) добавляется в LinearLayout, определяется во время выполнения.
Подвиды должны иметь фиксированную ширину 200dp. Поэтому при динамическом добавлении SubViews к Linearlayout я хочу проверить, достаточно ли места для другого SubView или нужно запустить новую строку. Ширина RowView должна быть переменной и НЕ обязательно равна размеру экрана.
Чтобы проверить, достаточно ли места, я просто вижу, меньше ли объединенная ширина всех SubViews, чем ширина Linearlayout - ширина одного SubView. Внутри моего пользовательского LinearLayout (RowView) это выглядит следующим образом:
public void addSubView(SubView v) {
int childcount = getChildCount();
int totalChildWidth = 0;
for(int i = 0; i < childcount; i++) {
totalChildWidth += getChildAt(i).getWidth();
}
if(totalChildWidth < getWidth() - 200) { // there is space left in this row
addView(v);
}
}
Проблема просто в том, что getWidth()
LinearLayout, и getWidth()
из уже добавленных SubViews возвращает 0, и, следовательно, проверка, достаточно ли места, идет не так.
Причина этого заключается в том, что я вызываю getWi´dtdh(), когда Views (UI) еще не отображены на экране, поэтому мой вопрос в том, когда подходящее время для вызова моего метода addSubView()? В настоящее время я вызываю его при создании фрагмента, что явно неправильно:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment, container, false);
RowView row = (RowView) v.findViewById(R.id.rowView);
ArrayList<SubView> subViews = DBManager.getSubViewList(); // connects to a database and returns all available subviews
for(int i = 0; i < subViews.size(); i++) {
row.addSubView(subViews.get(i));
}
return v;
}
Так, где вызвать мой метод addSubView(...), где гарантируется, что getWidth()
внутри это не вернет 0? И вообще, когда правильный момент (какой метод обратного вызова, согласно жизненному циклу Activity) для getWidth()
или же getHeight()
вида, который будет вызван, где гарантируется, что они не вернут 0?
Что я уже пробовал:
- Вызов
addSubView(...)
моего RowView в фрагментахonActivityCreated(...)
-> не работает - Подключиться к базе данных внутри RowViwes
onSizeChanged(...)
метод и всеaddSubView(...)
там -> не работает - Сделайте это, как описано в приведенном выше коде, но с обработчиком с задержкой 500 мс -> работает, потому что пользовательский интерфейс отображается, но не является для меня правильным решением
1 ответ
То, что вы пытаетесь сделать, не работает, так как верстка не закончена в тот момент, когда вы хотите узнать ширину элемента. Есть два решения. Первый - определить фактическую ширину вашего макета, что легко в вашем случае, так как это фактическая ширина экрана:
int width = getActivity().getResources().getDisplayMetrics().widthPixels
Используйте это значение, чтобы определить, сколько ваших подпредставлений вы можете добавить в одну строку, преобразовав 200dp
в пиксель:
int viewWidth = (int) (200 * (getActivity().getResources().getDisplayMetrics().densityDpi / 160f));
Затем вы можете рассчитать максимальное количество просмотров для строки:
int maxViewsToAdd = (int) width/viewWidth;
Другое решение - это globalLayoutListener
Вы можете найти описание здесь. Но это, кажется, не работает во всех случаях.