Подтвердить что ты не робот

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;
}
4b9b3361

Ответ 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