ViewPager图片轮播小练习

    xiaoxiao2021-03-25  307

    1. 图片轮播

    学习资料:

    Viewpager实现真正的无限滑动,拒绝Integer.MAX_VALUE安卓日记——用RxJava做轮播图

    十分感谢两位同学

    两个同学的思路大同小异,都没有采用将getCount()设置Integer.MAX_VALUE的常规思路,采用原理是基本是一致的,看懂一个,另外一个自然也就懂了

    原理

    在ViewPager的item队列中,首先添加原队尾,也就是5;然后再添加原队首1,最终比实际item多出两个

    原理图也直接拿来用了,我实际用坚果手机测试,这种方式带来的优化效果比设置 Integer.MAX_VALUE 方式几乎可以忽略。占用内存相差不大,使用这种方式,循环多次时,占用内存增长速度感觉稍微慢一点点。个人感觉,性能方面两种方式基本是一样的。但这种方式,更符合真正的循环轮播吧


    1.1 BannerAdapter

    主要是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个参数,是去除动画效果


    1.2 Activity

    运行效果

    布局文件:

    <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)


    2. 切换动画

    学习资料

    鸿洋大神的巧用ViewPager 打造不一样的广告轮播切换效果ViewPager实现画廊效果android-[译]两行代码搞定ViewPager的过渡动画 切换动画

    2.1 BannerTransformer

    public class BannerTransformer implements ViewPager.PageTransformer { private static final float MAX_SCALE = 1.0f; private static final float MIN_SCALE = 0.8f; @Override public void transformPage(View page, float position) { if (position < -1) {//(-Infinity,-1) page.setScaleX(MIN_SCALE); page.setScaleY(MIN_SCALE); } else if (position <= 0) {//[-1,0] float scaleFactor = MIN_SCALE+(1-Math.abs(position))*(MAX_SCALE-MIN_SCALE); page.setScaleX(scaleFactor); page.setScaleY(scaleFactor); } else if (position <= 1) {//(0,1] float scaleFactor = MIN_SCALE+(1-Math.abs(position))*(MAX_SCALE-MIN_SCALE); page.setScaleX(scaleFactor); page.setScaleY(scaleFactor); } else {//(1,Infinity) page.setScaleX(MIN_SCALE); page.setScaleY(MIN_SCALE); } } }

    切换动画使用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


    2.2 问题

    遇到一个坑,查了一个多小时,暂时也没有考虑出到底啥原因

    一开始在BannerAdapter中,重写的是finshUpdate(),右滑没有问题,左滑遇到一个问题

    遇到问题

    手指从右侧向左滑时,3个page每循环一次后,就会出现问题,左面的page会闪一下,然后大小变成原始的正常大小,设置的缩放效果无效

    将BannerAdapter中的finshUpdate()改为startUpdata()方法后,就好了

    若使用设置Integer.MAX_VALUE的方式,使用同一个切换动画,没有任何问题。

    转载请注明原文地址: https://ju.6miu.com/read-73.html

    最新回复(0)