android viewpager实现轮播效果

本文是基于ViewPager实现的无限自动轮播banner,供大家参考,具体内容如下

分为四步去实现:

第一步是有限手动轮播;

第二步是无限轮播;

第三步是自动轮播;

第四步是指示器适配

第一步:有限手动轮播实现

布局:

<androidx.viewpager.widget.ViewPager
    android:id="@+id/banner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="12dp"
    android:layout_marginEnd="12dp" />

adapter实现:

public class BannerAdapter extends PagerAdapter {
    
    private List<String> bannerList;
 
    public BannerAdapter(List<String> bannerList) {
        this.bannerList = bannerList;
    }
 
    @Override
    public int getCount() {
        return bannerList.size();
    }
 
    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }
 
    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        ImageView bannerImageView = new ImageView(container.getContext());
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        bannerImageView.setLayoutParams(lp);
        bannerImageView.setScaleType(ImageView.ScaleType.FIT_XY);
        Glide.with(container.getContext()).load(bannerList.get(position)).into(bannerImageView);
 
        container.addView(bannerImageView);
        return bannerImageView;
    }
 
    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
    }
}

Activity中:

// scrollview中viewpager一定要设置高度,此处根据图片的宽高比来设定高度
 
int bannerWidth = (Utils.getScreenWidth(getContext()) - Utils.dip2pixel(getContext(), 24));
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) bannerView.getLayoutParams();
lp.width = LinearLayout.LayoutParams.MATCH_PARENT;
lp.height = (int) (bannerWidth * 90f / 345);
bannerView.setLayoutParams(lp);
 
bannerView.setAdapter(new BannerAdapter(getUrlList()));

注意:ScrollView包裹ViewPager时,ViewPager的高度一定要有确定值,否则内容无法加载出来,可以在xml中指定,也可以代码设定,但一定要有确定值。

第二步:无限轮播

无限轮播只需要在有限轮播的基础上,做以下两个改动点,修改getCount返回值且在加载数据时获取正确的数据源即可

public class BannerAdapter extends PagerAdapter {
 
    private List<String> bannerList;
 
    public BannerAdapter(List<String> bannerList) {
        this.bannerList = bannerList;
    }
 
    @Override
    public int getCount() {
//        return bannerList.size();  // before
        return Integer.MAX_VALUE;   // now
    }
 
    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }
 
    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        ImageView bannerImageView = new ImageView(container.getContext());
        int realPosition = position % bannerList.size(); // 获取要加载数据的真实位置
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        bannerImageView.setLayoutParams(lp);
        bannerImageView.setScaleType(ImageView.ScaleType.FIT_XY);
//        Glide.with(container.getContext()).load(bannerList.get(position)).into(bannerImageView); // before
        Glide.with(container.getContext()).load(bannerList.get(realPosition)).into(bannerImageView); // now
 
        container.addView(bannerImageView);
        return bannerImageView;
    }
 
    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
    }
}

修改完发现banner只能向右无限轮播,第一次左滑滑不动,这个时候我们强制设置viewpager位置在中间就可以解决这个问题了

bannerView.setAdapter(new BannerAdapter(getUrlList()));
bannerView.setCurrentItem(getUrlList().size() * 5);

第三步:自动轮播

handler每隔轮播间隔发送消息,设置viewpager为下一个位置

private Runnable bannerRunnable = new Runnable() {
        @Override
        public void run() {
            bannerView.setCurrentItem(bannerView.getCurrentItem() + 1);
            mHandler.postDelayed(bannerRunnable, 3000);
        }
    };
 
bannerView.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
 
            }
 
            @Override
            public void onPageSelected(int position) {
                // 手滑动到某一位置,重新开始计时
                start();
            }
 
            @Override
            public void onPageScrollStateChanged(int state) {
 
            }
        });
 
private void start() {
        mHandler.removeCallbacksAndMessages(null);
        mHandler.postDelayed(bannerRunnable, 3000);
    }

第四步:添加指示器

指示器样式及表现可以自己去根据需求实现,以相对简单和常见的小圆圈指示器为例,添加和banner数量相同的小圆圈,小圆圈设置selector,在选中时为黑色选中样式,在非选中时为灰色默认样式,根据当前选中的banner的实际position,设置指示器的selected属性,从而展示不同的样式

private void initIndicator() {
        for (int i = 0; i < getUrlList().size(); i++) {
            View view = new View(getActivity());
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(Utils.dip2pixel(getActivity(), 6), Utils.dip2pixel(getActivity(), 6));
            lp.rightMargin = Utils.dip2pixel(getActivity(), 8);
            view.setLayoutParams(lp);
            view.setBackgroundResource(R.drawable.selector_indicator_view);
            view.setSelected(i == 0);
            llIndicatorView.addView(view);
        }
    }
 
 
private void initBannerView() {
        bannerView.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
 
            }
 
            @Override
            public void onPageSelected(int position) {
                // 手滑动到某一位置,重新开始计时
                realPosition = 0;
                realPosition = position % getUrlList().size();
                // 根据当前滑动到的banner设置指示器的状态
                for (int i = 0; i < llIndicatorView.getChildCount(); i++) {
                    llIndicatorView.getChildAt(i).setSelected(i == realPosition);
                }
                start();
            }
 
            @Override
            public void onPageScrollStateChanged(int state) {
 
            }
        });
    }

附:Utils文件

public class Utils {
    public static void setFullScreen(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
            activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
        }
    }
 
    public static int dip2pixel(Context context, float n) {
        int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, n, context.getResources().getDisplayMetrics());
        return value;
    }
 
    /**
     * 获取屏幕宽度
     * @param context
     * @return 屏幕宽度
     */
    public static int getScreenWidth(Context context) {
        WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.widthPixels;
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android使用viewpager实现自动无限轮播图

    1.具体步骤 说下大概实现步骤,一般我们有两种,一种是viewpager+作为游标的点 .另外一种是重写viewpager. 效果图: 1.1 布局,直接viewpager+一个viewgroup就好. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:

  • Android 使用ViewPager自动滚动循环轮播效果

    对Android 利用ViewPager实现图片可以左右循环滑动效果,感兴趣的朋友可以直接点击查看内容详情. 主要介绍如何实现ViewPager自动播放,循环滚动的效果及使用.顺便解决ViewPager嵌套(ViewPager inside ViewPager)影响触摸滑动及ViewPager滑动速度设置问题. 先给大家展示下效果图,喜欢的朋友可以下载源码: 1.实现 没有通过ScheduledExecutorService或Timer定期执行某个任务实现,而是简单的通过handler发送消息去

  • Android使用ViewPager加载图片和轮播视频

    作为Android基础组件之一,大家对viewpager已经很熟悉了,网上也有很多使用viewpager来加载图片的案例.但是像微信那样点击图片,可以轮播显示图片和视频的例子却没找到.正巧项目中有需求,可以就花时间写了下,现在给一下核心代码,希望对有此需求的同学们起一个抛砖引玉的作用.话不多说了,上代码: 以下是initData的代码 public void initData() { //把聊天界面的图片和视频找出来,并加到数组中,并在 //并根据传进来的position来找到视频或图片在数组中

  • Android实现基于ViewPager的无限循环自动播放带指示器的轮播图CarouselFigureView控件

    最近用到需要无限轮播自动播放的轮播轮播图,网上感觉都有这样那样的问题,于是自己写了一个通用的控件CarouselFigureView. 特点: 1.可以轮播view可以自己定义,不一定是要是ImageView2.指示器默认显示,但是可以隐藏3.可以设置指示器的颜色.间距.大小 4.有基础的可以自己修改代码改变指示器位置,这个应该不难5.可以自己开启和关闭自动轮播,开启轮播的时候可以设置轮播时间间隔,默认3000毫秒 我们先来看看效果图: 然后来看看使用代码 xml代码 <?xml version

  • Android 中使用 ViewPager实现屏幕页面切换和页面轮播效果

    之前关于如何实现屏幕页面切换,写过一篇博文<Android中使用ViewFlipper实现屏幕切换>,相比ViewFlipper,ViewPager更适用复杂的视图切换,而且Viewpager有自己的adapter,这也让其适应复杂对象,实现数据的动态加载. ViewPager是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api.而viewpager就是其中之一,利用它,我们可以做很多事情,从最简单的导航,到页面菜单等等. 下面我们就展示下Vie

  • Android使用ViewPager实现自动轮播

    很多APP中都实现了类似引导页的自动轮播,不由得想到昨天的引导页上修改一下代码实现轮播. 其实大体上只需要添加一个线程循环执行就可以了. 项目已同步至:https://github.com/nanchen2251/viewpagerDemo 同样的先上图 直接上代码,注释都全的,我想这样更有利于理解. 先改了Adapter  package com.example.nanchen.taketurnplaydemo; import android.support.v4.view.PagerAdap

  • Android Viewpager实现无限循环轮播图

    在网上找了很多viewpager实现图片轮播的,但是大多数通过以下方式在PagerAdapter的getCount()返回一个无限大的数,来实现 伪无限 @Override public int getCount() { return Integer.MAX_VALUE;//返回一个无限大的值,可以 无限循环 } 虽然通过这种方式是能达到效果,但是从严格意义上来说并不是真正的无限. 假如有五张轮播图 item的编号为(0,1,2,3,4) 要想实现 无限循环  我们在这五张的头部和尾部各加一张即

  • Android ViewPager实现无限循环轮播广告位Banner效果

    现在一些app通常会在头部放一个广告位,底部放置一行小圆圈指示器,指示广告位当前的页码,轮播展示一些图片,这些图片来自于网络.这个广告位banner是典型的android ViewPager实现,但是如果自己实现这样的ViewPager,要解决一系列琐碎的问题,比如: (1)这个广告位ViewPager要支持无限循环轮播,例如,有3张图片,A,B,C,当用户滑到最后C时候再滑就要滑到A,反之亦然. (2)ViewPager要实现自动播放,比如每个若干秒如2秒,自动切换播放到下一张图片. (3)通

  • Android ViewPager实现图片轮播效果

    在app中图片的轮播显示可以说是非常常见的实现效果了,其实现原理不过是利用ViewPager,然后利用handler每隔一定的时间将ViewPager的currentItem设置为当前item的position+1即可.先来看看效果图吧: 就是实现这样的一个轮播广告的效果. 因为这个是自己为了练习仿照某旅游类App做的,所以这里的数据是使用抓包工具抓取的,准备数据等工作就不在这里赘述了,反正数据的添加大体都是相同的.我的思路是这样的,从网络上实时的获取数据(当然你也可以将数据写死),然后通过网络

  • Android ViewPager实现轮播图效果

    先上一张效果图: 说到ViewPager实现轮播图效果,那么肯定会用到PagerAdapter,下面先介绍下这个类. PagerAdapter简介 PagerAdapter是Android.support.v4包中的类,是一个抽象类,直接继承于Object,导入包android.support.v4.view.PagerAdapter即可使用. PagerAdapter主要是viewpager的适配器,而viewPager则也是在android.support.v4扩展包中新添加的一个强大的控件

随机推荐