使用ViewPager实现自动轮播

最近实现了使用viewpager实现广告轮播,写个博客给自己记录一下,请各位看官批评指正。
首先,在布局文件中viewpager需要注意的是要把包名写全,

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

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

        <android.support.v4.view.ViewPager
            android:id="@+id/vp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#ccffee" />

        <LinearLayout
            android:id="@+id/indicator"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_marginBottom="5dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="5dp"
            android:gravity="center"
            android:orientation="horizontal" />
    </FrameLayout>

</LinearLayout>

线性布局indicator的作用是用来加载广告轮播或者图片浏览时下方的小圆点。

ViewPager中每个view视图的布局如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:orientation="vertical" >

    <ImageView 
        android:id="@+id/img"
        android:layout_width="100dp"
        android:layout_height="100dp"
        />

</LinearLayout>

这里我有一个疑惑,就是图片的大小设置好像并没有什么卵用,加载到viewpager中的视图的大小由viewpager的宽高决定。

在项目中,viewpager要显示的视图的数量一般不是固定的,所以需要我们动态加载视图,代码如下:

for (int i = 0; i < imgs.length; i++) {
            View v=LayoutInflater.from(this).inflate(R.layout.item_view, null);
            ImageView img=(ImageView)v.findViewById(R.id.img);
            img.setBackgroundResource(imgs[i]);

            imgList.add(img);
        }

图片底部小圆点的数量也需要动态添加,之前在布局中写了一个线性布局用来盛装小圆点的view ,动态加载小圆点代码如下:

// 创建底部指示位置的导航栏
        mBottomImages = new ImageView[imgList.size()];

        for (int i = 0; i < mBottomImages.length; i++) {
            ImageView imageView = new ImageView(this);
            //给圆点的view设置宽高,间距等属性
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    80, 80);

            params.setMargins(5, 0, 5, 0);
            //四个参数分别是左 上 右 下
            imageView.setLayoutParams(params);
            //初始状态给第一个小圆点设置选中状态
            if (i == 0) {
                imageView.setBackgroundResource(R.drawable.choosed);
            } else {
                imageView.setBackgroundResource(R.drawable.unchoose);
            }

            mBottomImages[i] = imageView;
            // 把指示作用的原点图片加入底部的视图中
            indicator.addView(mBottomImages[i]);

监听视图滑动的状态:

vp.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int arg0) {
                // TODO Auto-generated method stub
                //判断自动轮播到第几张图片,将当前显示的图片的小圆点设为选中的图片
                for (int j = 0; j < mBottomImages.length; j++) {
                    if (arg0 % imgList.size() == j) {
                        mBottomImages[j].setImageResource(R.drawable.choosed);
                    } else {
                        mBottomImages[j].setImageResource(R.drawable.unchoose);
                    }
                }
                autoCurrIndex = arg0;
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub
                //ViewPager.SCROLL_STATE_IDLE的状态时表明没有手动的滑动视图,isTouch代表是否在手动滑动的标志 如果用户手动在滑,将这个标志设为true
                if(arg0==ViewPager.SCROLL_STATE_IDLE){
                    isTouch=false;
                }else{
                    isTouch=true;
                }
            }
        });

写一个线程,用来发送空消息给主线程更新界面,实现自动轮播

Thread dt=new Thread(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            //isAuto标志代表是否在自动轮播,可以在activity销毁时将该状态设为 false
                while(isAuto){

                    try {
                        dt.sleep(4000);
                        mHandler.sendEmptyMessage(1);

                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }

        }
    });

在主线程中,写一个内部类 handler

// 定时轮播图片,需要在主线程里面修改 UI
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 1:
            //如果在手动滑动时,就停止自动轮播,等手动操作停止时,再继续轮播
                if(isTouch)
                    return;
                if(!isAuto)
                    return;
                //当前的位置+1
                autoCurrIndex++;
                vp.setCurrentItem(autoCurrIndex);
                break;
            }
        }
    };

在适配器中,需要注意,在instantiateItem方法中需要判断要显示的视图是否有parent,如果有要删掉,否则会抛出异常,因为一个view只能有一个parent,不能被viewgroup重复添加,不要在destroyItem中销毁视图,会出现白屏的情况。

private class MyAdapter extends PagerAdapter {
        private List<ImageView> list;

        public MyAdapter(List<ImageView> list) {
            this.list = list;
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            //设置成最大就可以一直向后滑,实现轮播的效果
            return Integer.MAX_VALUE;
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            // TODO Auto-generated method stub
            return arg0 == arg1;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // TODO Auto-generated method stub
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // TODO Auto-generated method stub
            int p = position % list.size();
            ImageView view = list.get(p);
            // 如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。
            ViewParent vp = view.getParent();
            if (vp != null) {
                ViewGroup parent = (ViewGroup) vp;
                parent.removeView(view);
            }

            container.addView(view);

            return list.get(p);
        }
    }

这样广告或图片自动轮播的功能就实现了,资源下载地址请戳:
http://download.csdn.net/detail/u012456602/9685109

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值