Android广告位循环轮播图的实现

这几天想要实现一个广告位的循环轮播图,遇到了一些问题,现在已经成功解决了,所以还是想分享一下。


首先,循环轮播图是通过定时切换ViewPager页实现的,但是如果按照常规的viewpager实现,则会遇到以下几个问题:

     1. 刚一打开界面的时候,ViewPager是不能向左滑动的。

   2.当从最后一页(假设只有四页)切换回第一页时,在视觉上会快速的向左划过第三页、第二页,最后回到第一页(这显然不是我们想看到的效果)。


下面我们来具体实现一下(需要注意的地方我就在代码中注释了):


①首先是xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.tangao.test.activtiy.LunBoTuActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="180dp">

        <android.support.v4.view.ViewPager
            android:id="@+id/main_tranFragment_topViewPager"
            android:layout_width="match_parent"
            android:layout_height="180dp" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:gravity="center"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/main_tranF_topVP_point1"
                android:layout_width="13dp"
                android:layout_height="13dp"
                android:padding="5dp"
                android:background="@drawable/viewpager_point_selected" />

            <ImageView
                android:id="@+id/main_tranF_topVP_point2"
                android:layout_width="13dp"
                android:layout_height="13dp"
                android:padding="5dp"
                android:background="@drawable/viewpager_point" />

            <ImageView
                android:id="@+id/main_tranF_topVP_point3"
                android:layout_width="13dp"
                android:layout_height="13dp"
                android:padding="5dp"
                android:background="@drawable/viewpager_point" />

            <ImageView
                android:id="@+id/main_tranF_topVP_point4"
                android:layout_width="13dp"
                android:layout_height="13dp"
                android:padding="5dp"
                android:background="@drawable/viewpager_point" />
        </LinearLayout>

    </FrameLayout>

</LinearLayout>



②Adapter部分

public class MyViewPagerAdapter extends PagerAdapter {

    private Context context;
    private List<ImageView> imageViewList;

    public MyViewPagerAdapter(Context context, List<ImageView> imageViewList){
        this.context = context;
        this.imageViewList = imageViewList;
    }

    @Override
    public int getCount() {
        /**
         * 这个方法的返回值是ViewPager的页数,不能返回imageViewList.size(),
         * 而是应该返回一个很大的值,这里的Integer.MAX_VALUE说明这个viewpager一共有Integer.MAX_VALUE页
         * 而这Integer.MAX_VALUE页就是由imageView中的各页 循环排列 而成的,如下:
         * 0 1 2 3 0 1 2 3 0 1 2 3 ...
         */

        return Integer.MAX_VALUE;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        /**
         * position是viewpager的页下标,取值范围为 0~getCount(),
         * 所以要想根据position取imageViewList里的东西,必须先取模
         */
        int index = position % imageViewList.size();
        container.addView(imageViewList.get(index));
        return imageViewList.get(index);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        /**
         * position须取模,理由同上
         */
        container.removeView(imageViewList.get(position % imageViewList.size()));
    }



    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }
}

③代码实现部分

public class LunBoTuActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {

    private ViewPager mViewPager;
    //viewpager显示的原图ID
    private int[] imageViewIds = {R.drawable.ic_launcher, R.drawable.qq_round,
            R.drawable.weixin_round, R.drawable.weibo_round};
    //要显示的viewpager页,图片转换而来的View们
    private List<ImageView> imageViewList = new ArrayList<ImageView>();
    //viewpager页对应的小圆点(view对象)
    private List<ImageView> dots = new ArrayList<ImageView>();

    //viewpager当前页的下标,千万别赋值为0!!!否则我们下面使用这个初值后,
    //出来的效果就是我们上面说到的第一个问题(不能向左滑)
    private int currentDotPosition = 400;//初始值还应该是imageViewList.size()的整数倍

    //用作定时触发
    private ScheduledExecutorService scheduleExecutorService;
    //    android.os中的Handler,注意!
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            System.out.println("Handler!");
            super.handleMessage(msg);
            mViewPager.setCurrentItem(currentDotPosition);//currentDotPosition取值范围为0~getCount()
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lun_bo_tu);

        initValues();
        initView();
    }

    private void initValues() {
        //添加要显示的viewpager页(view对象)
        for (int i = 0; i < imageViewIds.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setBackgroundResource(imageViewIds[i]);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageViewList.add(imageView);
        }

        //获取xml中的viewpager小圆点view对象
        dots.add((ImageView) findViewById(R.id.main_tranF_topVP_point1));
        dots.add((ImageView) findViewById(R.id.main_tranF_topVP_point2));
        dots.add((ImageView) findViewById(R.id.main_tranF_topVP_point3));
        dots.add((ImageView) findViewById(R.id.main_tranF_topVP_point4));

    }

    private void initView() {

        mViewPager = (ViewPager) findViewById(R.id.main_tranFragment_topViewPager);
        mViewPager.setAdapter(new MyViewPagerAdapter(this, imageViewList));//调用一次getCount()
        /**
         * 这里先要setCurrent一次,否则运行会有问题
         * 从这里可以看出,如果我们上面的currentDotPosition设置成0的话,运行后一开始便不能向左滑动
         * 如果设置成400,开始运行后就可以向左滑动400次(我还真试过!滑完了之后想,为什么我不先设置成10再试呢)
         */

        mViewPager.setCurrentItem(currentDotPosition);//调用一次getCount()
        mViewPager.addOnPageChangeListener(this);调用一次getCount()
    }


    @Override
    public void onStart() {
        /**
         * Activity呈现出来的时候,开始计时,触发
         */
        scheduleExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduleExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                currentDotPosition = currentDotPosition + 1;
                mHandler.obtainMessage().sendToTarget();//通过handler通知主UI更新界面
            }
        }, 1, 3, TimeUnit.SECONDS);//最开始延时1s,而后每3s触发一次
        super.onStart();
    }

    @Override
    public void onStop() {
        //Activity消失时,停止计时触发
        scheduleExecutorService.shutdown();
        super.onStop();

    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    /**
     * 监听到页的切换后,改变小圆点的亮度
     *
     * @param position
     */
    @Override
    public void onPageSelected(int position) {
        //position与setCurrentItem()中的参数相等,且取值都在0~getCount()--(integer.MAX_VALUE);
        //改变小圆点亮度
        currentDotPosition = position;//用手拨动时,需要给currentDotPosition赋值
        for (int i = 0; i < dots.size(); i++) {
            if ((position % dots.size()) == i) {
                dots.get(i).setBackgroundResource(R.drawable.viewpager_point_selected);
            } else {
                dots.get(i).setBackgroundResource(R.drawable.viewpager_point);
            }
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}


如此便大功告成了,以上代码可直接拷贝运行看效果(图片什么的自己放吧)。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值