instantiateItem(ViewGroup, int) in PagerAdapter and AddView in ViewPager confusion

后端 未结 2 2028
广开言路
广开言路 2020-12-04 15:05

So far I\'ve been hacking together examples to get a feel for the APIs the Android SDK as a whole. However, I\'ve hit an impasse.

I\'m trying to Inflate a LinearLay

相关标签:
2条回答
  • 2020-12-04 15:22

    I have the same misunderstanding how this adapter works and I have made some investigation.
    The key particularity is that your views are stored in two places:
    1 in ViewPager you add them by calling ((ViewPager) container).addView(view); (here you need to store only three views, what you see and left and right neighborhoods)
    2 in private final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>(); this is member of ViewPager there are stored views with information about they possition (they are added here by calling adapter method mAdapter.instantiateItem(this, position);)

    static class ItemInfo {
        Object object;
        int position;
        boolean scrolling;
        float widthFactor;
        float offset;
    }
    

    When you slides ViewPager gets view position from mItems array or instantiates it and compare this view with children of ViewPager with adapters method public boolean isViewFromObject(View view, Object object). View which is equals to object is displayed to user on ViewPager. If there is no view then the blank screen is displayed.
    Here is ViewPager method where view is compared to object:

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

    If views position from mItems is not in range {currentposition -1,currentposition +1} then it will be destroyed:

    mItems.remove(itemIndex);
    mAdapter.destroyItem(this, pos, ii.object);
    

    the view of ViewPagers memory 1

    It is one trap with destroyItem when you slides forward firs is called destroyItem and then new item is added, but when you slides backward first is added new item and then old is destroyed. If you try to use only three cached views you can get IllegalStateException: The specified child already has a parent. while sliding backwards.

    ViewPager memory

    0 讨论(0)
  • 2020-12-04 15:36

    I've recently implemented this and this is my instantiateItem method (made it a bit minimal for readability.

    @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;
    }
    

    So for the page that is displayed, I get the data from my evaluations list using the position as the index. Then inflate the Layout which has the views I will add my data too. Then I get the TextView to set the evaluation summary text on. Then the whole Layout is added to the ViewPager. And finally the Layout is also returned.

    If you still can't get it post your code.

    0 讨论(0)
提交回复
热议问题