ViewPager的使用:

public class MainActivity extends Activity
{
    /*
     * XML添加viewpager方法:
     *   <android.support.v4.view.ViewPager
     *   android:id="@+id/viewPager"
     *   android:layout_width="match_parent"
     *   android:layout_height="match_parent"/>
     */
                           
                           
    int[] ImageIds = new int[]
    { R.drawable.guide_daily_brand, R.drawable.guide_item_detail_1, R.drawable.guide_item_detail_2, R.drawable.guide_multi_shop_detail,
            R.drawable.guide_pic_mode, R.drawable.guide_timeline_filter };
                           
    private ArrayList<View> mViewList = new ArrayList<View>();
                           
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
                               
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
        viewPager.setAdapter(new PagerAdapter()
        {
            @Override
            public Object instantiateItem(View container, int position)
            {
                //第一页和最后一页只创建保留两个view来复用,中间则保留三个view
                LayoutInflater inflater = getLayoutInflater();
                View layout = inflater.inflate(R.layout.pager_item, null);
                                       
                //将View加入到容器和container里面,不加判断会造成泄漏
                if(mViewList.size() < ImageIds.length)
                {
                    mViewList.add(layout);
                }
                
                ((ViewPager) container).addView(layout, 0);
                                       
                layout.setBackgroundResource(ImageIds[position]);
                return layout;
            }
                                   
            @Override
            public void destroyItem(View container, int position, Object object)
            {
                //此处的position与上面的并不相等,会自动销毁不在当前页左右的view
                ((ViewPager) container).removeView(mViewList.get(position));
            }
                                   
            @Override
            public boolean isViewFromObject(View arg0, Object arg1)
            {
                return arg0 == arg1;//判断对象与类型
            }
                                   
            @Override
            public int getCount()
            {
                return ImageIds.length;
            }
        });
                               
    }
                           
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
                           
}




其他笔记:

1.viewpager切换时容易造成oom问题

mViewPager = (ViewPager) findViewById(R.id.photogallery_viewpager);
mAdapter = new PhotoGalleryAdapter();
//限制view的数量,减少view缓存,在setAdapter之前使用
mViewPager.setOffscreenPageLimit(3);
mViewPager.setAdapter(mAdapter);
mViewPager.setCurrentItem(mPagerSelected);


2.两种removeview方法

        @Override
        public void destroyItem(View container, int position, Object object)
        {
//             ((ViewPager) container).removeView((View) object);
            ((ViewPager) container).removeView(mViewList.get(position));
        }


3.关于notifyDataSetChanged()方法无法及时更新的问题解决方法

(1)销毁ViewItem时要使用以下方法:

        @Override
        public void destroyItem(View container, int position, Object object)
        {
//            ((ViewPager) container).removeView(mViewList.get(position));
             ((ViewPager) container).removeView((View)object);
        }

参考资料:http://www.myexception.cn/android/417891.html


(2)重写notifyDataSetChanged()和getItemPosition(Object object)方法,代码如下:

        private int mChildCount = 0;
        
        @Override
        public void notifyDataSetChanged()
        {
            mChildCount = getCount();
            super.notifyDataSetChanged();
        }
        
        @Override
        public int getItemPosition(Object object)
        {
            if (mChildCount > 0)
            {
                mChildCount--;
                return POSITION_NONE;
            }
            return super.getItemPosition(object);
        }


参考资料:http://www.cnblogs.com/maoyu417/p/3740209.html


附相关注释:

进入viewpager,我们终于找到了viewpager中控制数据变更的重点方法dataSetChanged ,这个方法如下:
      void dataSetChanged () {
        // This method only gets called if our observer is attached, so mAdapter is non-null.
 
        boolean needPopulate = mItems .size() < mOffscreenPageLimit * 2 + 1 &&
                mItems.size() < mAdapter.getCount();
        int newCurrItem = mCurItem ;
 
        boolean isUpdating = false;
        for (int i = 0; i < mItems.size(); i++) {
            final ItemInfo ii = mItems .get(i);
            final int newPos = mAdapter.getItemPosition(ii.object );
 
            if (newPos == PagerAdapter.POSITION_UNCHANGED ) {
                continue;
            }
 
            if (newPos == PagerAdapter.POSITION_NONE) {
                mItems.remove(i);
                i--;
 
                if (!isUpdating) {
                    mAdapter.startUpdate( this);
                    isUpdating = true;
                }
 
                mAdapter.destroyItem( this, ii.position , ii.object);
                needPopulate = true;
 
                if (mCurItem == ii.position ) {
                    // Keep the current item in the valid range
                    newCurrItem = Math. max(0, Math.min(mCurItem, mAdapter.getCount() - 1));
                    needPopulate = true;
                }
                continue;
            }
 
            if (ii.position != newPos) {
                if (ii.position == mCurItem ) {
                    // Our current item changed position. Follow it.
                    newCurrItem = newPos;
                }
 
                ii. position = newPos;
                needPopulate = true;
            }
        }
 
        if (isUpdating) {
            mAdapter.finishUpdate( this);
        }
 
        Collections. sort(mItems, COMPARATOR);
 
        if (needPopulate) {
            // Reset our known page widths; populate will recompute them.
            final int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = getChildAt(i);
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                if (!lp.isDecor ) {
                    lp. widthFactor = 0.f;
                }
            }
 
            setCurrentItemInternal(newCurrItem, false, true);
            requestLayout();
        }
    }
 
  重点看这样一行代码:
 final int newPos = mAdapter.getItemPosition(ii.object );
 
   if (newPos == PagerAdapter.POSITION_UNCHANGED ) {
         continue ;
   }
 
  官方对getItemPosition()的解释是:
  Called when the host view is attempting to determine if an item’s position has changed. Returns POSITION_UNCHANGED if the position of the given item has not changed orPOSITION_NONE if the item is no longer present in the adapter.
The default implementation assumes that items will never change position and always returns POSITION_UNCHANGED.
  意思是如果item的位置如果没有发生变化,则返回POSITION_UNCHANGED。如果返回了POSITION_NONE,表示该位置的item已经不存在了。默认的实现是假设item的位置永远不会发生变化,而返回POSITION_UNCHANGED
 
解决方案:
  所以我们可以尝试着修改适配器的写法,覆盖getItemPosition()方法,当调用notifyDataSetChanged时,让getItemPosition方法人为的返回POSITION_NONE,从而达到强迫viewpager重绘所有item的目的。