InstantiateItem в PagerAdapter и AddView в замешательстве ViewPager
До сих пор я взламывал примеры, чтобы получить представление об API-интерфейсах SDK от Anfroid в целом. Однако я зашел в тупик.
Я пытаюсь надуть LinearLayout двумя TextViews из файла XML. Это будут те виды, которые выложены. Я просто не могу заставить это работать и понять, что я полностью не понимаю, что происходит с кодом.
Посмотрев на источник, я вижу, что метод ViewPager.addNewItem вызывает InstantiateItem из поставляемого адаптера. И addNewItem вызывается в populate(). populate вызывается в ряде других мест.
В любом случае в примере, который я видел, когда метод переопределен для PagerAdapter, вы должны включить вызов AddView в Colletion ViewPager, который передается из viewpager в качестве аргумента.
Если я хочу добавить несколько представлений, я думал, что это будет случай вызова addView несколько раз, но поскольку instantiateItem возвращает объект в ViewPager (в примере, когда он возвращал представление, которое он добавил), я не знаю что вернуть. Я попытался вернуть завышенный вид и многое другое.
Пожалуйста, кто-нибудь может объяснить, что здесь происходит?
Большое значение.
M
@Override
public Object instantiateItem(View collection, int position) {
layout = inflater.inflate(R.layout.animallayout, null);
TextView tv = (TextView) layout.findViewById(R.id.textView1);
tv.setText("1________________>" + position);
TextView tv2 = (TextView) layout.findViewById(R.id.textView2);
tv.setText("2________________>" + position);
((ViewPager) collection).addView(layout);
return layout;
}
Ответы
Ответ 1
Недавно я реализовал это, и это мой метод instantiateItem
(сделал его немного минимальным для удобочитаемости.
@Override
public Object instantiateItem(View collection, int position) {
Evaluation evaluation = evaluations.get(position);
View layout = inflater.inflate(R.layout.layout_evaluation, null);
TextView evaluationSummary = (TextView) layout.findViewById(R.id.evaluation_summary);
evaluationSummary.setText(evaluation.getEvaluationSummary());
((ViewPager) collection).addView(layout);
return layout;
}
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((View) view);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
Итак, для отображаемой страницы я получаю данные из моего списка evaluations
, используя позицию в качестве индекса.
Затем раздуйте Layout
, в котором есть представления, и я добавлю свои данные.
Затем я получаю TextView
, чтобы установить итоговый текст оценки.
Затем все Layout
добавляется к ViewPager
.
И, наконец, возвращается Layout
.
Если вы все еще не можете получить его, разместите свой код.
Ответ 2
У меня такое же недоразумение, как работает этот адаптер, и я провел некоторое расследование.
Основная особенность заключается в том, что ваши взгляды хранятся в двух местах:
1 в ViewPager вы добавляете их, вызывая ((ViewPager) container).addView(view);
(здесь вам нужно хранить только три вида, то, что вы видите, а также слева и справа)
2 в private final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>();
, это член ViewPager, там хранятся представления с информацией об их возможностях (они добавляются сюда путем вызова метода адаптера mAdapter.instantiateItem(this, position);
)
static class ItemInfo {
Object object;
int position;
boolean scrolling;
float widthFactor;
float offset;
}
Когда вы перемещаете ViewPager
, получаем позицию представления из массива mItems
или создаете его и сравниваете это представление с дочерними элементами ViewPager
с помощью метода адаптеров public boolean isViewFromObject(View view, Object object)
. Вид, равный object
, отображается пользователю ViewPager
. Если нет представления, отображается пустой экран.
Вот метод ViewPager
, где представление сравнивается с объектом:
ItemInfo infoForChild(View child) {
for (int i=0; i<mItems.size(); i++) {
ItemInfo ii = mItems.get(i);
if (mAdapter.isViewFromObject(child, ii.object)) {
return ii;
}
}
return null;
}
Если позиция взгляда из mItems не находится в диапазоне {currentposition -1, currentposition +1}, то она будет уничтожена:
mItems.remove(itemIndex);
mAdapter.destroyItem(this, pos, ii.object);
вид памяти ViewPagers 1
Это одна ловушка с destroyItem
, когда вы перемещаете вперед firs, называется destroyItem
, а затем добавляется новый элемент, но когда вы перемещаетесь назад, сначала добавляется новый элемент, а затем старый уничтожается. Если вы попытаетесь использовать только три кэшированных вида, вы можете получить IllegalStateException: The specified child already has a parent.
при отклонении назад.
![ViewPager memory]()