android 使用viewpager实现广告轮播效果

第一步:用viewpager实现滑动。

 首先是页面布局fragment_home.xml,只定义了一个Viewpager,代码如下:

<RelativeLayout 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"
    tools:context="com.example.wmk.fragment.HomeFragment">

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

接着是,主界面fragment,主界面,只是为ViewPager 做了个适配器而已。

package com.example.wmk.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.example.wmk.R;

/**
 * HomeFragment
 */
public class HomeFragment extends Fragment {

    private int[] mImageIds = {R.mipmap.op01, R.mipmap.op02, R.mipmap.op03,
            R.mipmap.op04, R.mipmap.op05
    };

    /**
     * 首页布局容器
     */
    private View homeLayout;
    /**
     * ViewPager
     */
    private ViewPager vpHomeFragment;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        homeLayout = inflater.inflate(R.layout.fragment_home, container, false);

        //初始化
        initViews();
        //设置适配器
        vpHomeFragment.setAdapter(new MyViewPagerAdapter());


        return homeLayout;
    }


    private void initViews() {
        vpHomeFragment = (ViewPager) homeLayout.findViewById(R.id.vp_homeFragment);
    }

    class MyViewPagerAdapter extends PagerAdapter {
        @Override
        public int getCount() {

            /**
             * 返回图片的数量
             * 如果要使viewpager循环,直接返回比mImageIds.length大的值就可以了
             */
            return mImageIds.length;
        }

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

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView imageView = new ImageView(getActivity());
            imageView.setBackgroundResource(mImageIds[position]);
            container.addView(imageView);
            return imageView;
        }

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

mImageIds数组里面存放了5张的图片,用于实现图片轮播。 Viewpager滑动效果如下:



下面对第一步中的代码进行了改进,主要对MyViewPagerAdapter进行了封装,代码如下:

package com.example.wmk.adapter;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

/**
 * Created by 老王 on 2016/12/15.
 */
public class MyViewPagerAdapter extends PagerAdapter {

    /**
     * 上下文
     */
    private Context context;
    /**
     * 图片数组
     */
    private int[] mImageIds;

    public MyViewPagerAdapter(Context context, int[] mImageIds) {
        this.context = context;
        this.mImageIds = mImageIds;
    }

    @Override
    public int getCount() {

        /**
         * 返回图片的数量
         * 如果要使viewpager循环,直接返回比mImageIds.length大的值就可以了
         */
        return mImageIds.length;
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        ImageView imageView = new ImageView(context);
        imageView.setBackgroundResource(mImageIds[position]);
        container.addView(imageView);
        return imageView;
    }

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

想对应,主界面的代码如下:

package com.example.wmk.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.example.wmk.R;
import com.example.wmk.adapter.MyViewPagerAdapter;

/**
 * HomeFragment
 */
public class HomeFragment extends Fragment {

    private int[] mImageIds = {R.mipmap.op01, R.mipmap.op02, R.mipmap.op03,
            R.mipmap.op04, R.mipmap.op05
    };

    /**
     * 首页布局容器
     */
    private View homeLayout;
    /**
     * ViewPager
     */
    private ViewPager vpHomeFragment;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        homeLayout = inflater.inflate(R.layout.fragment_home, container, false);

        //初始化
        initViews();
        //设置适配器
        vpHomeFragment.setAdapter(new MyViewPagerAdapter(getActivity(), mImageIds));

        return homeLayout;
    }


    private void initViews() {
        vpHomeFragment = (ViewPager) homeLayout.findViewById(R.id.vp_homeFragment);
    }

第二步:实现滑动的过程中,对应的游标图片跟随滑动。

  首先是,主界面布局的代码,相对应的变化如下:

<RelativeLayout 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"
    tools:context="com.example.wmk.fragment.HomeFragment">

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

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="160dp"
        android:gravity="center">

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

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:src="@mipmap/shape_point_unselector" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:src="@mipmap/shape_point_unselector" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:src="@mipmap/shape_point_unselector" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:src="@mipmap/shape_point_unselector" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:src="@mipmap/shape_point_unselector" />
        </LinearLayout>

        <ImageView
            android:id="@+id/cur_dot"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/shape_point_selector" />
    </FrameLayout>

</RelativeLayout>

   布局效果图,如下:



 其次,主界面代码如下:

package com.example.wmk.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;

import com.example.wmk.R;
import com.example.wmk.adapter.MyViewPagerAdapter;

/**
 * HomeFragment
 */
public class HomeFragment extends Fragment {

    private int[] mImageIds = {R.mipmap.op01, R.mipmap.op02, R.mipmap.op03,
            R.mipmap.op04, R.mipmap.op05
    };

    /**
     * 首页布局容器
     */
    private View homeLayout;
    /**
     * ViewPager
     */
    private ViewPager vpHomeFragment;
    /**
     *
     */
    private ImageView curDot;

    // 位移量
    private int offset;

    // 记录当前的位置
    private int curPos = 0;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        homeLayout = inflater.inflate(R.layout.fragment_home, container, false);

        //初始化
        initViews();

        //设置适配器
        vpHomeFragment.setAdapter(new MyViewPagerAdapter(getActivity(), mImageIds));

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

            }

            @Override
            public void onPageSelected(int position) {
                int pos = position % mImageIds.length;
                moveCursorTo(pos);
                curPos = pos;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        return homeLayout;
    }

    /**
     * 移动指针到相邻的位置
     *
     * @param position 指针的索引值
     */
    private void moveCursorTo(int position) {
        TranslateAnimation anim = new TranslateAnimation(offset * curPos,
                offset * position, 0, 0);
        anim.setDuration(30);
        anim.setFillAfter(true);
        curDot.startAnimation(anim);
    }


    private void initViews() {
        vpHomeFragment = (ViewPager) homeLayout.findViewById(R.id.vp_homeFragment);
        curDot = (ImageView) homeLayout.findViewById(R.id.cur_dot);
        curDot.getViewTreeObserver().addOnPreDrawListener(
                new ViewTreeObserver.OnPreDrawListener() {
                    public boolean onPreDraw() {
                        offset = curDot.getWidth();
                        return true;
                    }
                });
    }
}

效果图如下:


下面对第二步中的主界面代码就行优化,代码如下:

package com.example.wmk.connector;

import android.support.v4.view.ViewPager;

/**
 * Created by 老王 on 2016/12/15.
 */
public class MyPageChangeListener implements ViewPager.OnPageChangeListener {

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

    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

package com.example.wmk.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;

import com.example.wmk.R;
import com.example.wmk.adapter.MyViewPagerAdapter;
import com.example.wmk.connector.MyPageChangeListener;

/**
 * HomeFragment
 */
public class HomeFragment extends Fragment {
    /**
     * 首页布局容器
     */
    private View homeLayout;
    /**
     * ViewPager
     */
    private ViewPager vpHomeFragment;
    /**
     * ImageView
     */
    private ImageView curDot;

    // 位移量
    private int offset;
    // 记录当前的位置
    private int curPos = 0;
    // 图片数组
    private int[] mImageIds = {R.mipmap.op01, R.mipmap.op02, R.mipmap.op03,
            R.mipmap.op04, R.mipmap.op05
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        homeLayout = inflater.inflate(R.layout.fragment_home, container, false);
        //初始化
        initViews();
        //监听事件
        initEvents();
        //设置适配器
        initSetAdapter();

        return homeLayout;
    }

    private void initViews() {
        vpHomeFragment = (ViewPager) homeLayout.findViewById(R.id.vp_homeFragment);
        curDot = (ImageView) homeLayout.findViewById(R.id.cur_dot);
    }

    private void initEvents() {
        /**
         * ViewPager监听事件
         */
        vpHomeFragment.addOnPageChangeListener(new MyPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                int pos = position % mImageIds.length;
                moveCursorTo(pos);
                curPos = pos;
            }
        });
        /**
         * 游标图片监听事件
         */
        curDot.getViewTreeObserver().addOnPreDrawListener(
                new ViewTreeObserver.OnPreDrawListener() {
                    public boolean onPreDraw() {
                        offset = curDot.getWidth();
                        return true;
                    }
                });
    }

    private void initSetAdapter() {
        vpHomeFragment.setAdapter(new MyViewPagerAdapter(getActivity(), mImageIds));
    }

    /**
     * 移动指针到相邻的位置
     *
     * @param position 指针的索引值
     */
    private void moveCursorTo(int position) {
        TranslateAnimation anim = new TranslateAnimation(offset * curPos,
                offset * position, 0, 0);
        anim.setDuration(30);
        anim.setFillAfter(true);
        curDot.startAnimation(anim);
    }
}

第三步,实现图片手动轮播。

     主要就是对适配器进行修改,代码如下:

package com.example.wmk.adapter;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

/**
 * Created by 老王 on 2016/12/15.
 */
public class MyViewPagerAdapter extends PagerAdapter {

    /**
     * 上下文
     */
    private Context context;
    /**
     * 图片数组
     */
    private int[] mImageIds;

    public MyViewPagerAdapter(Context context, int[] mImageIds) {
        this.context = context;
        this.mImageIds = mImageIds;
    }

    @Override
    public int getCount() {

        /**
         * 返回图片的数量
         * 如果要使viewpager循环,直接返回比mImageIds.length大的值就可以了
         */
        return Integer.MAX_VALUE;
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        int pos = position % mImageIds.length;
        ImageView imageView = new ImageView(context);
        imageView.setBackgroundResource(mImageIds[pos]);
        container.addView(imageView);
        return imageView;
    }

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

第四步,实现图片的自动轮播。通过handler发送一条延时消息机制,实现图片自动轮播,代码如下:

package com.example.wmk.fragment;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;

import com.example.wmk.R;
import com.example.wmk.adapter.MyViewPagerAdapter;
import com.example.wmk.connector.MyPageChangeListener;

/**
 * HomeFragment
 */
public class HomeFragment extends Fragment {
    /**
     * 首页布局容器
     */
    private View homeLayout;
    /**
     * ViewPager
     */
    private ViewPager vpHomeFragment;
    /**
     * ImageView
     */
    private ImageView curDot;

    // 位移量
    private int offset;
    // 记录当前的位置
    private int curPos = 0;
    // 图片数组
    private int[] mImageIds = {R.mipmap.op01, R.mipmap.op02, R.mipmap.op03,
            R.mipmap.op04, R.mipmap.op05
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        homeLayout = inflater.inflate(R.layout.fragment_home, container, false);
        //初始化
        initViews();
        //监听事件
        initEvents();
        //设置适配器
        initSetAdapter();
        //发送消息
        initSendMessage();

        return homeLayout;
    }

    private void initViews() {
        vpHomeFragment = (ViewPager) homeLayout.findViewById(R.id.vp_homeFragment);
        curDot = (ImageView) homeLayout.findViewById(R.id.cur_dot);
    }

    private void initEvents() {
        /**
         * ViewPager监听事件
         */
        vpHomeFragment.addOnPageChangeListener(new MyPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                int pos = position % mImageIds.length;
                moveCursorTo(pos);
                curPos = pos;
            }
        });
        /**
         * 游标图片监听事件
         */
        curDot.getViewTreeObserver().addOnPreDrawListener(
                new ViewTreeObserver.OnPreDrawListener() {
                    public boolean onPreDraw() {
                        offset = curDot.getWidth();
                        return true;
                    }
                });
    }

    private void initSetAdapter() {
        vpHomeFragment.setAdapter(new MyViewPagerAdapter(getActivity(), mImageIds));
    }


    private void initSendMessage() {
        //延时两秒发送消息
        mHandler.sendEmptyMessageDelayed(0, 2000);
    }

    /**
     * 移动指针到相邻的位置
     *
     * @param position 指针的索引值
     */
    private void moveCursorTo(int position) {
        TranslateAnimation anim = new TranslateAnimation(offset * curPos,
                offset * position, 0, 0);
        anim.setDuration(30);
        anim.setFillAfter(true);
        curDot.startAnimation(anim);
    }

    /**
     * 广告条的自动轮播效果,将页面自动切换到下一个页面
     * 实现方法之一:可以利用handler发送一条延时消息
     * 实现方法之二:可以利用定时器
     */
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            int currentItem = vpHomeFragment.getCurrentItem();//获取viewPager当前页面的位置
            vpHomeFragment.setCurrentItem(++currentItem);

            //继续发送延时两秒的消息,类似递归的效果,使广告一直切换
            mHandler.sendEmptyMessageDelayed(0, 2000);

            /**
             * 当用户触摸的时候,自动轮播就应该停止下来
             */
            vpHomeFragment.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            mHandler.removeCallbacksAndMessages(null);
                            break;
                        case MotionEvent.ACTION_UP:
                            mHandler.sendEmptyMessageDelayed(0, 2000);
                            break;
                        default:
                            break;
                    }
                    /**
                     * 如果这里返回trueviewPager的事件将会被消耗掉,ViewPager将会响应不了
                     * 所以这里要返回false,让viewPager原生的触摸效果正常运行
                     */
                    return false;
                }
            });
        }
    };
}


猜你喜欢

转载自blog.csdn.net/qq_21200053/article/details/53670019