自定义View系列之ViewPager实现广告条效果

今天我学习了使用ViewPager实现广告条的效果,以后项目中也可以使用

来看代码,首先是xml布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
   >

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="wrap_content"
        android:layout_height="200dp"></android.support.v4.view.ViewPager>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/viewpager"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="666"
            android:gravity="center"/>

        <LinearLayout
            android:id="@+id/dot_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_gravity="center_horizontal">

        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

然后在Activity中实例化:

 mViewPager = (ViewPager) findViewById(R.id.viewpager);
        dot_layout = (LinearLayout) findViewById(R.id.dot_layout);
        tv_text = (TextView) findViewById(R.id.tv_text);

设置ViewPager的Adapter:

mViewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return Integer.MAX_VALUE;
            }

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

            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                int realPosition = position%imageViewList.size();
                ImageView imageView = imageViewList.get(realPosition);
                container.addView(imageView);

                System.out.println("instantiateItem  position" + position);
                return imageView;
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView((View) object);
                System.out.println("destroyItem  position" + position);
            }
        });

图片资源:

private int[] images = {
            R.drawable.a,
            R.drawable.b,
            R.drawable.c,
            R.drawable.d,
            R.drawable.e
    };

这样一个简单的ViewPager就是实现好了。

1下面来看一下图片下面小圆点的实现:

这里我们可以这样做,在LinearLayout中addView数量为images.lenth的ImageView,然后给每个imageView设置图片资源,可以用select来做,也可以用两张不同原色图片来做,这里我就用select来做,然后监听ViewPager的滑动事件,滑动到哪张图片根据position给那个小圆点设置为高亮,前一个小圆点就变为正常,代码如下:

select代码:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/normal" android:state_enabled="false" />
    <item android:drawable="@drawable/selected" android:state_enabled="true" />
</selector>

图片资源文件,这里用shape来做:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <size android:height="8dp" android:width="8dp"/>
    <solid android:color="#44000000"/>
</shape>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <size android:height="8dp" android:width="8dp"/>
    <solid android:color="#d61212"/>
</shape>




Viewpager的滑动监听:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                int realPosition = position % imageViewList.size();
                dot_layout.getChildAt(preposition).setEnabled(false);
                dot_layout.getChildAt(realPosition).setEnabled(true);
                preposition = realPosition;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

2.实现左右无限滑动的效果:

实现无限滑动的效果网上都是在adapter的getCount方法中设置出一个很大的值,然后Viewpager开始的时候用setCurrentItem设置在中间的位置,这样就可以左右滑动了

这里注意的是,Viewpager是每次只能实例化最多3个View,比如说有0,1,2,3,张图片,一开始ViewPager就实例化了0和1张图片,当我滑动到图片1时,图片2就被实例化了,当我又滑动到图片2时,图片3就被实例化了,而图片0就被remove掉,以此类推。

上代码:

首先改写getCount方法,这里最好使用Short.MAX_VALUE,避免Viewpager的卡顿

@Override
            public int getCount() {
                return Integer.MAX_VALUE;

然后在开始的时候把Viewpager设置为中间页:

这里我的图片是5张,所以用此算法来得到item是5的整数倍

int item = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % imageViewList.size();//保证item是5的整数倍
        mViewPager.setCurrentItem(item);

然后在onPagerSelect方法中:

int realPosition = position % imageViewList.size();
                dot_layout.getChildAt(preposition).setEnabled(false);
                dot_layout.getChildAt(realPosition).setEnabled(true);
                preposition = realPosition;

还有在instantiateItem方法中:
int realPosition = position%imageViewList.size();
                ImageView imageView = imageViewList.get(realPosition);
                container.addView(imageView);

                System.out.println("instantiateItem  position" + position);
                return imageView;

此时运行程序就可以实现上面1和2的效果了


3.自动滑动

思路:使用handler实现:

private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            int item = mViewPager.getCurrentItem() + 1;
            mViewPager.setCurrentItem(item);
            handler.sendEmptyMessageDelayed(0, 4000);
        }
    };

然后在程序启动时发出消息:

handler.sendEmptyMessageDelayed(0, 4000);

4.当手指按下时停止滑动:

思路:监听imageview的onTouch事件,当MotionEvent为down时取消之前发的消息,当为Up时再继续发送消息

for (int i = 0; i < images.length; i++) {
            ImageView imageView = new ImageView(this);

            imageView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            //当手指按下的时候移除消息
                            handler.removeCallbacksAndMessages(null);
                            break;
                        case MotionEvent.ACTION_UP:
                            //当手指放开的时候再发送消息
                            handler.sendEmptyMessageDelayed(2, 4000);
                            break;
                    }
                    return true;
                }

此时运行程序,发现当我手指按下时能停止滑动,手指松开后确实还能继续滑动,但是当我拖拽图片到另一页的时候,会发现图片再也不会自动滑动了,原因是因为当我们拖动

图片时,手指松开时并不会触发up事件,而是触发了viewpager传送过来的MotionEvent.CANCEL事件,所以我们可以在MotionEvent.CANCEL事件中也加上发消息的代码,这时再启动程序会发现之前的问题解决了,但是新的问题又出现了,当你拖拽图片不到一半并按住图片停止时,图片会自动地转到了下一页,因为此时我们的在MotionEvent.CANCEL中已经发送了消息,4秒之后会跳到下一页,而此时我们还停止在原来的地方,自然而然4秒之后就跳到下一页了,所以此时我们要在viewpager的onPageScrollStateChanged方法中做处理

@Override
            public void onPageScrollStateChanged(int state) {
                System.out.println("state" + state);
                Log.i("tag", "state" + state);

                if (state == ViewPager.SCROLL_STATE_DRAGGING) {//如果当前状态是拖拽状态时
                    isDragging = true;
                    handler.removeCallbacksAndMessages(null);//把之前的消息移除掉
                } else if (state == ViewPager.SCROLL_STATE_IDLE && isDragging) {//如果当前状态是静止状态并且是拖拽过来的
                    isDragging = false;
                    handler.sendEmptyMessageDelayed(4, 4000);//当拖拽来另一个页面时再发消息
                }
            }
        });

定义一个boolean型变量,当拖拽时我们设置为true并且把消息移除,表示已经拖拽了,当viewpager静止状态时,如果isDragging为ttrue,即表示当前页面是拖拽过来的就重新发消息,并且把isDragging设置为false,此时启动程序会发现之前的问题都已经解决了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值