1. 程式人生 > >ViewPager 輪播圖 功能齊全

ViewPager 輪播圖 功能齊全

/*寫VIewPager的佈局
<android.support.v4.view.ViewPager
        android:id="@+id/viewpager_vp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />*/

//凡是註釋帶222的是優化,先把不帶222的程式碼填完,在填222,222主要做的是就是根據viewpager動態的顯示對應的文字和點
//凡是註釋帶333的是優化,先把222的程式碼填完,在填333,333主要做的是就是根據使viewpager能無限左右滑動.且能夠自動滑動,當用戶觸控時滑動結束,不互動時滑動繼續.
//採用動態新增點的邏輯,所以使用時,直接修改imageResIds descs 資源就行
public class MainActivity extends AppCompatActivity {

    private LinearLayout ll_dots;
    private TextView viewpager_tv;

    //    將ViewPager定義為全域性變數,方便使用.
    private ViewPager viewpager_vp;

    //    建立一個ArrayList集合.泛型指定為ImageView.
    ArrayList<ImageView> imageViews = new ArrayList<ImageView>();

 

    //建立一個handler物件,複寫handlerMessage方法,用switch方法,通過msg.what得到標識.333
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    //得到當前VIewPager和使用者互動的item條目.VIewPager物件.getCurrentItem 333
                    int currentItem = viewpager_vp.getCurrentItem();
                    //設定ViewPager當前顯示的介面,得到的ITem+1
                    viewpager_vp.setCurrentItem(currentItem + 1);
                    //通過靜態方法sendEmptyMessageDelayed,延時重複執行命令.注意不是sendEmptyMessageAtTime 333
                    sendEmptyMessageDelayed(1, 3000);
                    break;
                default:
                    break;
            }

        }
    };

    //圖片int陣列資源
    private int[] imageResIds = {R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e, R.drawable.f};

    //圖片字串陣列String[]資源.
    private String[] descs = {
            "網頁設計師聯盟",
            "教程網",
            "PS聯盟",
            "25學堂",
            "課工場帶你逆襲,助你走向人生巔峰",
            "當你因需求被專案經理頻繁修改,而想之暴打時,請先看易老師賤笑圖,你是不是更想打我了"
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //對控制元件進行初始化
        init();
    }

    /**
     * 對VIewPager進行初始化.
     */
    private void init() {
        //找到可以設定點的容器LinearLayout的物件,進行點的新增
        ll_dots = (LinearLayout) findViewById(R.id.ll_dots);
        //找到文字的物件.
        viewpager_tv = (TextView) findViewById(R.id.viewpager_tv);
        //找到VIewPager物件.
        viewpager_vp = (ViewPager) findViewById(R.id.viewpager_vp);

        //更加圖片int陣列資源的數量,動態的建立ImageView控制元件.就是有幾張圖片,建立幾個ImageView,for迴圈
        for (int x = 0; x < imageResIds.length; x++) {
            //建立ImageView物件
            ImageView imageView = new ImageView(this);
            //通過該物件新增圖片資源.setBackgroundResource方法.
            imageView.setBackgroundResource(imageResIds[x]);
            //把控制元件新增到集合ImageViews中去,以方便在VIewPager的介面卡裡instantiateItem方法獲取.
            imageViews.add(imageView);
            //進行點的新增,其個數和圖片的個數一致,因此放到該迴圈中.222
            dot();
        }

        //設定介面卡.setAdapter
        viewpager_vp.setAdapter(new Myadapter());
        //設定ViewPager的滑動監聽器,addOnPageChangeListener,set的方法因為名字的原因被淘汰了,在onPageScrolled中.222
        viewpager_vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {


            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                //同過getCurrentItem方法拿到當前使用者所互動ViewPager的item位置.
                int currentItem = viewpager_vp.getCurrentItem();
                //通過得到的這個item,給text和點進行選中的設定.
                changeTextAndDot(currentItem % imageResIds.length);
                Log.d("aaa", "onPageScrolled:   Position-" + position + "  positionOffset-" + positionOffset + " positionOffsetPixels-" + positionOffsetPixels);

            }

            @Override
            public void onPageSelected(int position) {
                Log.d("aaa", "onPageSelected: position" + position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                Log.d("aaa", "onPageScrollStateChanged: state" + state);
            }
        });
        //指定VIewPager預設跳轉到某頁.一般是最大數的一般.setCurrentItem就是設定VIewPager跳到哪頁,get是獲取.333
        viewpager_vp.setCurrentItem(Integer.MAX_VALUE / 2 - 3);

        //通過handler,3秒後開始迴圈ViwePager的item.sendEmptyMessageDelayed,333
        handler.sendEmptyMessageDelayed(1, 3000);
        //設定VIewPager的觸控事件.最後抽成方法.333
        ViewPagerTouchEvent();
    }

    /**
     * 注意:看一個方法或類的資訊快捷鍵:Ctrl+Q;
     * 像ListVIew一樣,建立一個ViewPager的介面卡,自定義一個類繼承PagerAdapter
     */
    private class Myadapter extends PagerAdapter {
        //getContent,設定ViewPager的條目個數.一般就是集合或者資源陣列的長度.
        @Override
        public int getCount() {
            //把返回的條目設定為無限大.333
            //注意:一般和獲取ViewPager當前選中的是第幾頁有關的都要改為position(當前頁數)%list.size()(取餘數),你就看哪報錯,根據報錯改333
            return Integer.MAX_VALUE;
        }

        //isViewFromObject,判斷ViewPager的條目View物件和InstantiateItem返回的Object物件是否一致,固定格式:return view==object;
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        //Ctrl+H:看到一個類的基礎結構圖    ctrl+h+l:快速格式化.
        //instantiateItem,ViewPager新增條目的操作.container:VIewPager的化身,控制元件都是新增到他身上,position:代表使用者滑動條目的位置
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            //根據條目所在位置(利用Position),從ImageViews集合裡獲取相對應的ImageVIew圖片.
            ImageView imageView = imageViews.get(position % imageResIds.length);
            //把得到ImageView物件,新增給VIewPager物件,也就是container,使用addView
            container.addView(imageView);
            //注意:你新增給VIewPager什麼控制元件,就要返回該控制元件,給isViewFromObject進行比較判斷,這裡新增的是ImageView,返回的就是ImageView
            return imageView;
        }

        //防止記憶體洩漏.相當於ListView的複用container,銷燬一個page,該方法的實際就是將instantiateItem返回的VIew物件從ViewPager中移除,
        //container:還是ViewPager控制元件自身 position: object:則代表了View控制元件,使用時要強轉成View一下
        //補充:為什麼引數是Object,而不直接是View,因為雖然99%是view,但也有可能是Fragment,所以用Object,提高了可擴充套件性.
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            //構造方法刪除後,也是固定格式:container.removeView((View) object);
            container.removeView((View) object);
        }
    }


    /**
     * 更加圖片資源的數量,動態的建立點222
     */
    public void dot() {
        //建立一個View物件;
        View view = new View(this);
        //為這個View物件設定背景setBackgroundResource
        view.setBackgroundResource(R.drawable.dot_normal);
        //為View物件設定寬高參數,使用引數物件LayoutParams(int,int),給哪個容器,就用哪個容器建立
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(8, 8);
        //使用引數物件LayoutParams.leftMargin=int,相當於佈局裡的padding.
        layoutParams.leftMargin = 8;
        //把準備好的layoutParams引數物件,設定給View物件.setLayoutParams
        view.setLayoutParams(layoutParams);
        //最後容器物件.addView(VIwe);
        ll_dots.addView(view);
    }


    /**
     * 根據ViewPager的item的變化,也就是圖片切換的操作,設定對應的點和文字.222
     *
     * @param position int ViewPager的item,也是圖片的位置
     */
    public void changeTextAndDot(int position) {
        //根據ViewPager的item的變化,設定對應的文字.setText(descs[position]);
        viewpager_tv.setText(descs[position]);
        //對點進行判斷是否是當前頁的點,用for迴圈,拿到所有點的位置,然後和position對比
        for (int x = 0; x < imageResIds.length; x++) {
            //.getChildAt(x);拿到容器的子控制元件.得到VIew物件
            View childAt = ll_dots.getChildAt(x);
            //為View設定背景圖片,,使用三元運算子.
            childAt.setBackgroundResource(x == position ? R.drawable.dot_focus : R.drawable.dot_normal);
        }
    }

    /**
     * 該方法主要設定VIewPager的觸控事件,實現使用者的觸控時,不再自動播放.switch中motionEvent.getActivity.333
     * 另一種實現的思路,是在ViewPager監聽事件裡面,對ViewPager的狀態進行判斷.閒置-滑動,和使用者互動中-移除滑動.
     * public void onPageScrollStateChanged(int state) {
     * //當滑動狀態發生改變的時候,手動滑動的時候,不能進行介面切換操作
     * //SCROLL_STATE_IDLE : 空閒狀態
     * if (state == ViewPager.SCROLL_STATE_IDLE) {
     * //自動切換介面
     * handler.sendEmptyMessageDelayed(VIEWPAGER_SWITCH_PAGE, 3000);
     * }else{
     * //停止自動切換
     * //停止介面切換操作
     * handler.removeMessages(VIEWPAGER_SWITCH_PAGE);
     * }
     * }
     */
    public void ViewPagerTouchEvent() {
        viewpager_vp.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        //當時MotionEvent.ACTION_DOWN和ACTION_MOVE,就移除handler傳送的message.removeMessages.333
                        handler.removeMessages(1);
                        break;
                    case MotionEvent.ACTION_MOVE:
                        handler.removeMessages(1);
                        break;
                    //當用戶手鬆開時ACTION_UP,就繼續使用sendEmptyMessageDelayed傳送handler的訊息.333
                    case MotionEvent.ACTION_UP:
                        handler.sendEmptyMessageDelayed(1, 3000);
                    default:
                        break;
                }
                return false;
            }
        });
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeMessages(1);
    }
}