1. 程式人生 > >Android ViewPager+Handler實現無限輪播和監聽處理事件時輪播速度越來越快的問題解決

Android ViewPager+Handler實現無限輪播和監聽處理事件時輪播速度越來越快的問題解決

大家都知道android的無限輪播實現的方法有很多,我們先來看看ViewPager+Handler吧:

一.ViewPager+Handler實現無限輪播    點選下載原始碼

package com.demo.sb.main;

import java.util.ArrayList;
import com.demo.sb.utils.DensityUtil;
import com.demo.suibian.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
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.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MActivity_Luenbo extends Activity {

    private ViewPager viewPager;
    private LinearLayout group;
    private int[] images = { R.drawable.a, R.drawable.c, R.drawable.d,
            R.drawable.guide_1, R.drawable.guide_2 };
    private ArrayList<ImageView> mImageViewList;
    private ImageView[] diandian;// ViewPager上的點點
    private int selectedItem = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mactivity_luenbo);
        viewPager = (ViewPager) findViewById(R.id.vp_viewPager);
        group = (LinearLayout) findViewById(R.id.ll_viewGroup);
        init();

    }

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            viewPager.setCurrentItem(selectedItem + 1);
            mHandler.sendEmptyMessageDelayed(0, 3000);
        };
    };

    private void init() {
        // TODO Auto-generated method stub
        // 引導3個ViewPager
        mImageViewList = new ArrayList<ImageView>();
        for (int i = 0; i < images.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setBackgroundResource(images[i]);
            mImageViewList.add(imageView);
        }

        // 將點點加入到ViewGroup中
        diandian = new ImageView[images.length];
        for (int i = 0; i < images.length; i++) {
            // 迴圈加入點點圖片組
            diandian[i] = new ImageView(this);
            if (i == 0) {
                diandian[i].setImageResource(R.drawable.page_indicator_focused);
            } else {
                diandian[i]
                        .setImageResource(R.drawable.page_indicator_unfocused);
            }
            diandian[i].setPadding(8, 8, 8, 8);
            group.addView(diandian[i]);
        }
        viewPager.setAdapter(new GuideAdapter());
        // 設定監聽,主要是設定點點的背景
        viewPager.setOnPageChangeListener(new GuidePagerListener());
        // 設定ViewPager的預設項,設定為長度的1000倍,這樣開始就能向左滑動了
        viewPager.setCurrentItem((images.length) * 1000);
    }

    /**
     * 每次當onResume有焦點時傳送個空訊息開始輪播
     */
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        mHandler.sendEmptyMessageDelayed(0, 2000);
    }

    /**
     * 當暫停時停止輪播
     */
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        mHandler.removeCallbacksAndMessages(null);
    }

    /**
     * ViewPager的介面卡
     * 
     */
    private class GuideAdapter extends PagerAdapter {

        @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(View container, int position, Object object)
        // {
        // // TODO Auto-generated method stub
        // ((ViewGroup) container).removeView(images[position
        // % images.length]);
        // }
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // TODO Auto-generated method stub
            container.removeView((View) object);
        }

        /**
         * 載入圖片進去,用當前的position除以圖片陣列長度取餘數是關鍵
         */
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // TODO Auto-generated method stub
            final int currentIten = position % images.length;
            ImageView iView = mImageViewList.get(currentIten);
            try {

                if (iView.getParent() == null) {
                    container.addView(iView);
                }
                iView.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View arg0) {
                        // TODO Auto-generated method stub
                        DensityUtil.showToast(MActivity_Luenbo.this,
                                currentIten + "");
                    }
                });
                iView.setOnTouchListener(new NewTouchListener());
            } catch (Exception e) {
                // TODO: handle exception
            }

            return iView;
        }

    }

    /**
     * ViewPager 的滑動監聽
     * 
     * @author Administrator
     * 
     */
    private class GuidePagerListener implements OnPageChangeListener {

        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub
            System.out.println(arg0 + "  dd " + arg1 + "  dddd  " + arg2);
        }

        @Override
        public void onPageSelected(int position) {
            // TODO Auto-generated method stub
            selectedItem = position;
            System.out.println("第幾個頁面" + position + "  " + position
                    % mImageViewList.size());
            for (int i = 0; i < diandian.length; i++) {
                if (i == position % images.length) {
                    diandian[i]
                            .setImageResource(R.drawable.page_indicator_focused);
                } else {
                    diandian[i]
                            .setImageResource(R.drawable.page_indicator_unfocused);
                }
            }
        }

    }

    /**
     * ViewPager的觸控事件當按下圖片停止輪播
     * 
     * @author Administrator
     * 
     */
    private class NewTouchListener implements OnTouchListener {

        @Override
        public boolean onTouch(View arg0, MotionEvent arg1) {
            // TODO Auto-generated method stub
            switch (arg1.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mHandler.removeCallbacksAndMessages(null);
                break;
            case MotionEvent.ACTION_CANCEL:
                mHandler.sendEmptyMessageDelayed(0, 3000);
                break;
            case MotionEvent.ACTION_UP:
                mHandler.sendEmptyMessageDelayed(0, 3000);
                break;
            default:
                break;
            }
            return true;
        }

    }

}

1 .在ViewPager的介面卡中的getCount()長度設定無限大Integer.MAX_VALUE
2 . 明白當前currentIten 為position % images.length;
3 . 設定一開始ViewPager的位置 viewPager.setCurrentItem((images.length) * 1000);這樣剛開始就可以向左滑動了
4 . 在OnPageChangeListener ViewPager的滑動監聽中設定小點的位置
5 . 設定Handler 定時滑動開啟滑動
6 . 在onResume中傳送空訊息,在onPause中移除訊息將所有的Callbacks和Messages全部清除掉,避免記憶體洩露。

上面這種的無限輪播要注意一個問題,那就是輪播圖在滑動的後會越來越快,這要注意下面的觸控監聽了:
  /**
     * ViewPager的觸控事件當按下圖片停止輪播
     * 
     * @author Administrator
     * 
     */
    private class NewTouchListener implements OnTouchListener {

        @Override
        public boolean onTouch(View arg0, MotionEvent arg1) {
            // TODO Auto-generated method stub
            switch (arg1.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mHandler.removeCallbacksAndMessages(null);
                break;
            case MotionEvent.ACTION_CANCEL:
                mHandler.sendEmptyMessageDelayed(0, 3000);
                break;
            case MotionEvent.ACTION_UP:
                mHandler.sendEmptyMessageDelayed(0, 3000);
                break;
            default:
                break;
            }
            return true;
        }

    }

在按下的時候加入下面的一行程式碼:
mHandler.removeCallbacksAndMessages(null);
二.UltraViewPager來實現,用UltraViewPager可以很簡單的實現無限輪播      點選下載原始碼

1.佈局:

<?xml version="1.0" encoding="utf-8"?>
<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.xieer.citybike.app.activity.guide.GuideActivity">

    <com.tmall.ultraviewpager.UltraViewPager
        android:id="@+id/ultra_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/darker_gray" />

    <Button
        android:id="@+id/guide_start"
        android:layout_width="90dp"
        android:layout_height="40dp"
        android:background="#FCCCC7"
        android:textSize="12sp"
        android:textColor="#D0525D"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="50dp"
        android:text="開始"
        android:visibility="gone" />
</RelativeLayout>

2.程式碼:
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import com.tmall.ultraviewpager.UltraViewPager;
import com.xieer.citybike.app.MainActivity;
import com.xieer.citybike.app.R;
import com.xieer.citybike.app.adapter.PageMyAdapter;
import com.xieer.citybike.app.utils.common.ToastUtils;

import java.util.ArrayList;

/**
 * 引導頁面
 * 使用UltraViewPager 來實現的輪播效果
 * 
 */
public class GuideActivity extends AppCompatActivity {
    private SharedPreferences sPreferences;
    private ArrayList<ImageView> mdata;
    private static final int[] mImageIds = new int[]{R.drawable.guide_1,R.drawable.guide_2,R.drawable.guide_3};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_guide);
        mdata = new ArrayList<>();
        for(int i=0;i<mImageIds.length;i++){
            ImageView imageView = new ImageView(this);
            imageView.setBackgroundResource(mImageIds[i]);
            mdata.add(imageView);
        }
        sPreferences = getSharedPreferences("info",MODE_PRIVATE);
        final Button btn_start = (Button)findViewById(R.id.guide_start);
        UltraViewPager ultraViewPager = (UltraViewPager)findViewById(R.id.ultra_viewpager);
        ultraViewPager.setScrollMode(UltraViewPager.ScrollMode.HORIZONTAL);
        PagerAdapter adapter = new PageMyAdapter(this,mdata);
        ultraViewPager.setAdapter(adapter);
        //設定indicator樣式
        ultraViewPager.initIndicator();
        ultraViewPager.getIndicator().setOrientation(UltraViewPager.Orientation.HORIZONTAL)
                .setFocusColor(Color.GREEN)
                .setNormalColor(Color.WHITE)
                .setMargin(0,0,0, ToastUtils.dp2px(this,10))
                .setRadius((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,ToastUtils.dp2px(this,4),this.getResources().getDisplayMetrics()));
        ultraViewPager.getIndicator().setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
        ultraViewPager.getIndicator().build();
        ultraViewPager.setInfiniteLoop(false);
        ultraViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                if(position == mdata.size() - 1){
                   btn_start.setVisibility(View.VISIBLE);
                }else {
                    btn_start.setVisibility(View.GONE);
                }
            }
        });
        btn_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sPreferences.edit().putBoolean("isLoad",false).commit();
                startActivity(new Intent(GuideActivity.this, MainActivity.class));
                finish();
            }
        });
    }
}

三.RollViewPager無限輪播點選,程式碼就不貼了,需要的可以私聊,直接發你    點選下載原始碼