学习资料:
Viewpager实现真正的无限滑动,拒绝Integer.MAX_VALUE安卓日记——用RxJava做轮播图十分感谢两位同学
两个同学的思路大同小异,都没有采用将getCount()设置Integer.MAX_VALUE的常规思路,采用原理是基本是一致的,看懂一个,另外一个自然也就懂了
原理在ViewPager的item队列中,首先添加原队尾,也就是5;然后再添加原队首1,最终比实际item多出两个
原理图也直接拿来用了,我实际用坚果手机测试,这种方式带来的优化效果比设置 Integer.MAX_VALUE 方式几乎可以忽略。占用内存相差不大,使用这种方式,循环多次时,占用内存增长速度感觉稍微慢一点点。个人感觉,性能方面两种方式基本是一样的。但这种方式,更符合真正的循环轮播吧
主要是startUpdate()方法的重写
public class BannerAdapter extends PagerAdapter { private List<String> imageViews = new ArrayList<>(); private int bannerSize; @Override public int getCount() { bannerSize = imageViews.size(); return bannerSize; } public void setImageViews(List<String> imageViews) { this.imageViews.addAll(imageViews); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView imageView = new ImageView(container.getContext()); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); String url = imageViews.get(position); Glide.with(container.getContext()).load(url).into(imageView); container.addView(imageView); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } @Override public void startUpdate(ViewGroup container) { ViewPager vp = (ViewPager) container; int position = vp.getCurrentItem(); if (position == 0) { position = bannerSize - 2; vp.setCurrentItem(position, false); } else if (position == (bannerSize - 1)) { position = 1; vp.setCurrentItem(position, false); } } }在startUpdate()方法中,根据滑动到的当前的position来确定最终的CurrentItem。当position为0时,就设置CurrentItem为原队尾;当positon为新队列的最后时,就设置CurrentItem为1
vp.setCurrentItem(position, false)中第2个参数,是去除动画效果
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false"> <android.support.v4.view.ViewPager android:id="@+id/banner_activity_vp" android:layout_width="match_parent" android:layout_height="180dp" android:layout_centerInParent="true" android:layout_marginLeft="30dp" android:layout_marginRight="30dp" android:clipChildren="false" /> </RelativeLayout>RelativeLayout和ViewPager的布局中都使用,android:clipChildren="false",主要是为了让ViewPager一屏幕可以显示多个item,显示多少则由android:layout_marginLeft这个系列的属性控制
Activity代码:
public class BannerActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_banner); initView(); } private void initView() { List<String> imageViews = new ArrayList<>(); imageViews.add(Urls.IMG_URL3);//添加队尾 imageViews.add(Urls.IMG_URL1); imageViews.add(Urls.IMG_URL2); imageViews.add(Urls.IMG_URL3); imageViews.add(Urls.IMG_URL1);//添加队首 ViewPager vp = (ViewPager) findViewById(R.id.banner_activity_vp); BannerAdapter adapter = new BannerAdapter(); vp.setPageMargin(10); adapter.setImageViews(imageViews); vp.setOffscreenPageLimit(3); vp.setAdapter(adapter); vp.setCurrentItem(1);//显示img_url_1 } }在imageViews中,多添加了两个img_url,由于添加了一个新的队首,设置vp.setCurrentItem(1)
学习资料
鸿洋大神的巧用ViewPager 打造不一样的广告轮播切换效果ViewPager实现画廊效果android-[译]两行代码搞定ViewPager的过渡动画 切换动画切换动画使用vp.setPageTransformer(true, new BannerTransformer())
动画就涉及到了一个缩放效果
一个page的position为0代表它处于中间,为1代表它完全处于右边,为-1代表它完全处于左边
由page_a切换到page_b,page_a从0.0f --> -1.0f,而page_b从1.0f --> 0.0f
遇到一个坑,查了一个多小时,暂时也没有考虑出到底啥原因
一开始在BannerAdapter中,重写的是finshUpdate(),右滑没有问题,左滑遇到一个问题
遇到问题手指从右侧向左滑时,3个page每循环一次后,就会出现问题,左面的page会闪一下,然后大小变成原始的正常大小,设置的缩放效果无效
将BannerAdapter中的finshUpdate()改为startUpdata()方法后,就好了
若使用设置Integer.MAX_VALUE的方式,使用同一个切换动画,没有任何问题。