Android ViewPager的無限循環制作Banner 以及調節viewpager的滑動速度

效果圖


主要的自定義類

import android.content.Context;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;

import java.util.ArrayList;
import java.util.List;

/**
 * android banner圖
 */
public class RollHeaderView extends FrameLayout implements OnPageChangeListener {

    private Context mContext;
    private ViewPager mViewPager;
    private LinearLayout mDotLl;
    private List<Integer> mUrlList;

    private List<ImageView> dotList = null;
    private MyAdapter mAdapter = null;
    private Handler mHandler = null;
    private AutoRollRunnable mAutoRollRunnable = null;

    private int prePosition = 0;

    private HeaderViewClickListener headerViewClickListener;

    public RollHeaderView(Context context) {
        this(context, null);
    }

    public RollHeaderView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RollHeaderView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.mContext = context;
        initView();
        initData();
        initListener();
    }

    //初始化view
    private void initView() {
        View.inflate(mContext, R.layout.view_header, this);
        mViewPager = (ViewPager) findViewById(R.id.vp);
        mDotLl = (LinearLayout) findViewById(R.id.ll_dot);

        //讓banner的高度是屏幕的1/4
        ViewGroup.LayoutParams vParams = mViewPager.getLayoutParams();
        vParams.height = (int) (DisplayUtil.getMobileHeight(mContext) * 0.25);
        mViewPager.setLayoutParams(vParams);
    }

    //初始化數據
    private void initData() {
        dotList = new ArrayList<>();
        mAutoRollRunnable = new AutoRollRunnable();
        mHandler = new Handler();
        mAdapter = new MyAdapter();
    }

    private void initListener() {
        mViewPager.addOnPageChangeListener(this);
    }


    /**
     * 設置數據
     *
     * @param urlList
     */
    public void setImgUrlData(List<Integer> urlList) {
        this.mUrlList = urlList;
        if (mUrlList != null && !mUrlList.isEmpty()) {
            //清空數據
            dotList.clear();
            mDotLl.removeAllViews();
            ImageView dotIv;
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            for (int i = 0; i < mUrlList.size(); i++) {
                dotIv = new ImageView(mContext);
                if (i == 0) {
                    dotIv.setBackgroundResource(R.drawable.bg_point_select);
                } else {
                    dotIv.setBackgroundResource(R.drawable.bg_point_normal);
                }
                //設置點的間距
                params.setMargins(0, 0, DisplayUtil.dip2px(mContext, 5), 0);
                dotIv.setLayoutParams(params);

                //添加點到view上
                mDotLl.addView(dotIv);
                //添加到集合中, 以便控制其切換
                dotList.add(dotIv);
            }
        }

        mAdapter = new MyAdapter();
        mViewPager.setAdapter(mAdapter);

        //設置viewpager初始位置, +10000就夠了
        mViewPager.setCurrentItem(urlList.size() + 10000);
        startRoll();
    }


    /**
     * 設置點擊事件
     *
     * @param headerViewClickListener
     */
    public void setOnHeaderViewClickListener(HeaderViewClickListener headerViewClickListener) {
        this.headerViewClickListener = headerViewClickListener;
    }


    //開始輪播
    public void startRoll() {
        mAutoRollRunnable.start();
    }

    // 停止輪播
    public void stopRoll() {
        mAutoRollRunnable.stop();
    }

    private class AutoRollRunnable implements Runnable {

        //是否在輪播的標誌
        boolean isRunning = false;

        public void start() {
            if (!isRunning) {
                isRunning = true;
                mHandler.removeCallbacks(this);
                mHandler.postDelayed(this, 3000);
            }
        }

        public void stop() {
            if (isRunning) {
                mHandler.removeCallbacks(this);
                isRunning = false;
            }
        }

        @Override
        public void run() {
            if (isRunning) {
                mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
                mHandler.postDelayed(this, 3000);
            }
        }
    }

    public interface HeaderViewClickListener {
        void HeaderViewClick(int position);
    }

    private class MyAdapter extends PagerAdapter {

        //爲了複用
        private List<ImageView> imgCache = new ArrayList<ImageView>();

        @Override
        public int getCount() {
            //無限滑動
            return Integer.MAX_VALUE;
        }

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

        @Override
        public Object instantiateItem(ViewGroup container, final int position) {

            ImageView iv;

            //獲取ImageView對象
            if (imgCache.size() > 0) {
                iv = imgCache.remove(0);
            } else {
                iv = new ImageView(mContext);
            }
            iv.setScaleType(ScaleType.FIT_XY);

            iv.setOnTouchListener(new OnTouchListener() {
                private int downX = 0;
                private long downTime = 0;

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            mAutoRollRunnable.stop();
                            //獲取按下的x座標
                            downX = (int) v.getX();
                            downTime = System.currentTimeMillis();
                            break;
                        case MotionEvent.ACTION_UP:
                            mAutoRollRunnable.start();
                            int moveX = (int) v.getX();
                            long moveTime = System.currentTimeMillis();
                            if (downX == moveX && (moveTime - downTime < 500)) {//點擊的條件
                                //輪播圖回調點擊事件
                                headerViewClickListener.HeaderViewClick(position % mUrlList.size());
                            }
                            break;
                        case MotionEvent.ACTION_CANCEL:
                            mAutoRollRunnable.start();
                            break;
                    }
                    return true;
                }
            });

            //加載圖片
//            Glide.with(mContext).load()
//                    .error(R.mipmap.ic_launcher).into(iv);
            iv.setImageResource(mUrlList.get(position % mUrlList.size()));

            container.addView(iv);

            return iv;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            if (object != null && object instanceof ImageView) {
                ImageView iv = (ImageView) object;
                container.removeView(iv);
                imgCache.add(iv);
            }
        }
    }

    @Override
    public void onPageSelected(int position) {
        dotList.get(prePosition).setBackgroundResource(R.drawable.bg_point_normal);
        dotList.get(position % dotList.size()).setBackgroundResource(R.drawable.bg_point_select);
        prePosition = position % dotList.size();
    }

    @Override
    public void onPageScrollStateChanged(int arg0) {

    }

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {

    }


    //停止輪播
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        stopRoll();
    }
}

圓點指示器的 樣式

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <solid android:color="@color/colorGary" />
    <size
        android:width="5dp"
        android:height="5dp" />
</shape>

輪播佈局樣式(也就是一個viewpager 然後後面一個layout 用作添加圓點指示器,當然這個界面樣式你可以隨意寫)


<?xml version="1.0" encoding="utf-8"?>
<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/vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="true"
        android:focusableInTouchMode="true" />

    <!--<TextView-->
    <!--android:id="@+id/desc"-->
    <!--android:layout_width="match_parent"-->
    <!--android:layout_height="wrap_content"-->
    <!--android:layout_alignBottom="@+id/vp" />-->

    <LinearLayout
        android:id="@+id/ll_dot"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/vp"
        android:layout_alignParentRight="true"
        android:layout_margin="10dp"
        android:gravity="center"
        android:orientation="horizontal"></LinearLayout>

</RelativeLayout>


Activity的代碼


import android.app.Activity;
import android.os.Bundle;

import java.util.ArrayList;

public class MainActivity extends Activity {


    //String list[] = {"'梅卡拉'豔情出軌", "芳島燕子穿比基尼大秀身材", "上海年輕失足女的自述", "90後美女無畏世俗眼光 嘗試裸模"};
    int IMG[] = {R.mipmap.img1, R.mipmap.img2, R.mipmap.img3, R.mipmap.img4};

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

        RollHeaderView rollHeaderView = (RollHeaderView) findViewById(R.id.roll);
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < IMG.length; i++) {
            list.add(IMG[i]);
        }
        rollHeaderView.setImgUrlData(list);


    }


}


Activity 的佈局樣式


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/bannerlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#D4D4D4"
    android:orientation="vertical">


    <com.example.vsat.test.RollHeaderView
        android:id="@+id/roll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </com.example.vsat.test.RollHeaderView>

</RelativeLayout>


實現了以上的代碼 基本上就可以 實現無限輪播了


如果想要調節viewpager的滑動速度 我們則需要實現viewpager的滑動類


import android.content.Context;
import android.support.v4.view.ViewPager;
import android.view.animation.Interpolator;
import android.widget.Scroller;

import java.lang.reflect.Field;

/**
 * Created by Administrator on 2016/11/11 0011.
 */

public class ViewPagerScroller extends Scroller {

    private int mScrollDuration = 2000; // 滑動速度

    /**
     * 設置速度速度
     *
     * @param duration
     */
    public void setScrollDuration(int duration) {
        this.mScrollDuration = duration;
    }

    public ViewPagerScroller(Context context) {
        super(context);
    }

    public ViewPagerScroller(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }

    public ViewPagerScroller(Context context, Interpolator interpolator,
                             boolean flywheel) {
        super(context, interpolator, flywheel);
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        super.startScroll(startX, startY, dx, dy, mScrollDuration);
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy) {
        super.startScroll(startX, startY, dx, dy, mScrollDuration);
    }

    public void initViewPagerScroll(ViewPager viewPager) {
        try {
            Field mScroller = ViewPager.class.getDeclaredField("mScroller");
            mScroller.setAccessible(true);
            mScroller.set(viewPager, this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


使用自定義之後的滑動類


ViewPagerScroller pagerScroller = new ViewPagerScroller(this);
pagerScroller.setScrollDuration(1000);//設置時間,時間越長,速度越慢
pagerScroller.initViewPagerScroll(viewpager);

只需要把viewpager 設置進去就可以了,很簡單,這樣就實現了所有的東西了


主要的東西都貼上了  源碼 也就沒必要了


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章