1. 程式人生 > >Android使用ViewPager實現圖片輪播(高度自適應,左右迴圈,自動輪播)

Android使用ViewPager實現圖片輪播(高度自適應,左右迴圈,自動輪播)

效果

前言

該效果實現是基於我的第一篇部落格 Android使用ViewPager實現引導頁(帶小點提示)進行改進的,因此部分相同的地方我不會再重複描述,有意全面瞭解的可以先看完該篇部落格。

實現

為實現自定義一個通用的控制元件,我們首先建立一個類繼承ViewPager,涉及的幾個功能點都在此類裡實現。
功能一、高度自適應
思路:前提是必須約定傳入圖片的寬高比例,然後按【螢幕寬度×(圖片高度/圖片寬度)】計算出輪播控制元件的高度,控制元件的寬度則匹配螢幕寬度,以保證圖片能夠顯示完全以及不被部分拉伸。
1.為了傳入圖片的寬高用於計算比例,我們需要在res/values資料夾下建立attrs.xml,在裡面自定義我們的屬性和宣告我們的樣式:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="imgWidth" format="integer"/>
    <attr name="imgHeight" format="integer"/>

    <declare-styleable name="CarouselViewPager">
        <attr name="imgWidth"/>
        <attr name="imgHeight"/>
    </declare-styleable>

</resources>

2.然後在佈局檔案中宣告我們自定義的ViewPager控制元件,並新增自定義的屬性值:

    <com.kinth.cantonfair.view.CarouselViewPager
        android:id="@+id/vp_carousel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/black"
        custom:imgWidth="640"
        custom:imgHeight="225"
        />
使用custom欄位必須要在最外層容器控制元件裡新增一句xmlns:custom="http://schemas.android.com/apk/res-auto"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

3.然後在我們自定義的ViewPager的構造方法裡取得對應的屬性值:
    private Context mContext;
    private int imgWidth;
    private int imgHeight;
    private ScrollRunnable rollRunnable;

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

    public CarouselViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CarouselViewPager, 0, 0);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.CarouselViewPager_imgWidth:
                    imgWidth = a.getInt(attr, 0);
                    break;
                case R.styleable.CarouselViewPager_imgHeight:
                    imgHeight = a.getInt(attr, 0);
                    break;
            }
        }
        a.recycle();
操作完成後不要忘記呼叫TypedArray的recycle()方法回收資源。

4.接著即可在onMeasure方法裡取得螢幕寬度,然後按照寬高比例計算並設定控制元件的高度了:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int screenWidth = DeviceUtil.getDeviceWidth(mContext);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(screenWidth, screenWidth * imgHeight / imgWidth);
        setLayoutParams(params);
    }
    public static int getDeviceWidth(Context context) {
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(metrics);
        return metrics.widthPixels;
    }

功能二、左右迴圈

思路:由於ViewPager本身並不支援迴圈輪播,所以在這裡用了一個比較取巧的辦法,即在第一張圖的前面新增一張圖並設定為最後一張圖的內容,而最後一張圖的後面也如是並設定為第一張圖的內容,如此對應,然後呼叫ViewPager的setCurrentItem(int item)方法並取消動畫效果來修改當前位置,如下圖所示:

實現程式碼:

    private List<View> getAllCarouselPages() {
        List<View> views = new ArrayList<View>();
        for (int i = 0; i < 6; i++) {
            views.add(getCarouselPage(i));
        }
        return views;
    }

    private View getCarouselPage(int i) {
        View root = getLayoutInflater().inflate(R.layout.include_carousel_page, null);
        ImageView ivCarouselPage = (ImageView) root.findViewById(R.id.iv_carousel_page);
        switch (i) {
            case 0:
                ivCarouselPage.setImageResource(R.mipmap.page_carousel_04);
                break;
            case 1:
                ivCarouselPage.setImageResource(R.mipmap.page_carousel_01);
                break;
            case 2:
                ivCarouselPage.setImageResource(R.mipmap.page_carousel_02);
                break;
            case 3:
                ivCarouselPage.setImageResource(R.mipmap.page_carousel_03);
                break;
            case 4:
                ivCarouselPage.setImageResource(R.mipmap.page_carousel_04);
                break;
            case 5:
                ivCarouselPage.setImageResource(R.mipmap.page_carousel_01);
                break;
        }
        return ivCarouselPage;
    }

另外,在操作過程中發現,往往上一張圖片還沒完全劃出setCurrentItem方法就已經呼叫了,從而導致切換不流暢,為此,我們需要在在自定義控制元件中新增頁面切換監聽,判斷當前頁面然後延時呼叫setCurrentItem方法,以保證完整顯示圖片後才修改位置:
        addOnPageChangeListener(new SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                if (position == 0) {
                    postDelayed(new Runnable() {    //延遲200使過渡效果更好,不然會導致未完全滑動至下一頁就切換
                        @Override
                        public void run() {
                            setCurrentItem(getAdapter().getCount() - 2, false);//false表示取消動畫效果
                        }
                    }, 200);
                } else if (position == getAdapter().getCount() - 1) {
                    postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            setCurrentItem(1, false);
                        }
                    }, 200);
                }
            }
        });

功能三、自動輪播

思路:自然是使用定時器去呼叫setCurrentItem方法進行切換,而其中,最簡單的當屬上文所使用的postDelayed(Runnable runnable, long delayMillis)方法了,通過延時呼叫本身方法實現定時任務:

    public void startAutoScroll() {
        postDelayed(rollRunnable, 3000);
    }

    class ScrollRunnable implements Runnable {
        @Override
        public void run() {
            setCurrentItem(getCurrentItem() + 1);
            startAutoScroll();
        }
    }
還有一種情況是,當用戶手動滑動Viewpager時我們需要停止自動輪播,為此,我們可以在使用者手指按下控制元件時移除任務,然後在手指離開控制元件時重新開始任務:
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                stopAutoScroll();
                break;
            case MotionEvent.ACTION_UP:
                startAutoScroll();
                break;
        }
        return super.onTouchEvent(ev);
    }
    public void stopAutoScroll() {
        removeCallbacks(rollRunnable);
    }

原始碼

相關推薦

Android使用ViewPager實現圖片(高度適應左右迴圈動輪)

效果 前言 該效果實現是基於我的第一篇部落格 Android使用ViewPager實現引導頁(帶小點提示)進行改進的,因此部分相同的地方我不會再重複描述,有意全面瞭解的可以先看完該篇部落格。 實現 為實現自定義一個通用的控制元件,我們首先建立一個類繼承ViewPager

viewPager+photoView實現圖片和手勢縮放功能 支援手勢縮放的imageView 如何實現相簿左右滑動和手勢縮放 如何讓圖片適應控制元件大小 photoView如何使用(上)

import uk.co.senab.photoview.IPhotoView; import uk.co.senab.photoview.PhotoViewAttacher; import uk.co.senab.photoview.PhotoViewAttacher.OnMatrixChangedList

iOS開發項目實戰——Swift實現圖片與瀏覽

0.10 上網 timer類 開發項目 cas hub string obj tle 近期開始開發一個新的iOS應用,自己決定使用Swift。進行了幾天之後,發現了一個非常嚴峻的問題。那就是無論是書籍,還是網絡資源,關於Swift的實在是太少了,隨便一

CSS/HTML/JS實現圖片

class fff 瀏覽器 tro back 全局 實現圖 func 原理 實現原理 將點擊的a標簽的href屬性值賦給img標簽的src屬性,這樣有個好處,就是如果瀏覽器不支持js的話,點擊a標簽也可跳轉到圖片地址看到圖片,不會影響內容的呈現 註:需要導入jquery

使用JQuery實現圖片效果

left 簡述 flow href 集合 jpg -i round 輪播 【效果如圖】 【原理簡述】 這裏大概說一下整個流程: 1,將除了第一張以外的圖片全部隱藏, 2,獲取第一張圖片的alt信息顯示在信息欄,並添加點擊事件 3,為4個按鈕添加點擊偵聽,點擊相應的按鈕,用

原生JS實現圖片

讓其 gin 偏移量 adding char 效率 lin doc 動畫效果 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8">

Flexslider插件實現圖片、文字圖片相結合滑動切換效果

remove 12px body 類型 ons art cal 選項 csharp 插件下載:   點擊下載 密碼: fbeg Flexslider具有以下特性: 支持滑動和淡入淡出效果。 支持水平、垂直方向滑動。 支持鍵盤方向鍵控制。 支持觸控滑動。 支

使用Ajax+jQuery來實現前端收到的數據在console上顯示+簡單的主頁設計與bootstrap插件實現圖片

value size 靠譜 實現圖 active length oot function 想要 1.實現前端輸入的數據在console上顯示 上一篇是解決了在前端的輸入信息在cygwin上顯示,這次要給前臺們能看見的數據,因為數據庫裏插入的數據少,所以寫的語句翻來覆去就那幾

C# winform窗體實現圖片

1、定義一個方法設定控制元件 和執行緒時間 /// <summary> /// 改變圖片 /// </summary> /// <param name="img">圖片</param>

微信小程式實現圖片

wxml頁面程式碼: <!--圖片輪播 --> <view class='swipercontainer'> <swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" inte

[程式碼] 使用css3實現圖片

使用css3實現圖片輪播 前言:實現圖片輪播的方式有很多種 ,例如js ,css 等等。 本文主要講述使用純css3實現輪播圖 工具介紹: 使用的編輯器: Hbuilder 進入正題 htm

html中使用JS實現圖片效果

HTML 部分 <div id="bannner" class="main_center_bannar">

html+css+js簡單實現圖片效果

<script>  index=0;function show_img(){             imgs=document.getElementById("shidian_img").children; //獲取所以圖片 並且儲存到陣列imgs數組裡             for(i =0

純css3實現圖片

用css3的動畫可以實現圖片輪播 無非就是兩種型別:  左右滾動型別, 漸變型別 1 左右滾動 定義一個大盒子 在一個小盒子裡面 裝3張圖片(這裡用3張圖片為例子) 三張圖片可以向左浮動,大盒子 overflow :hidden 小盒子增加css3

jquery實現圖片圖效果

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style> *{ padding:0; margin:0; list-style:n

用原生JS實現 圖片切換 功能

效果如圖:程式碼如下:<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title

JavaScript實現圖片和滑鼠懸停顯示

例: 提前放好了四張圖片,並編號。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www

JS原生程式碼實現圖片無縫切換的一種思路

JS實現圖片輪播是個老生常談的問題,也是新手的必由之路,在這裡提供一種思路,供大家參考: 1.生成DIV做外框,並設定overflow:hidden;  // 每個方法都必須有的 2.建立一個數組arr,放置圖片地址 3.生成兩個並排的圖片img1,img2,初始化圖片地址

+【CSS3】使用純css程式碼實現圖片效果

 使用純CSS3程式碼實現簡單的圖片輪播。 基本思路: 以5張圖片為例: 1.基本佈局: 將5張圖片左浮動橫向並排放入一個div容器(#photos)內,圖片設定統一尺寸,div寬度設定5個圖片的總尺寸,然後放入相框容器div(#frame),相框設定1個圖片

vue.js中使用swiper外掛實現圖片

第一步:安裝swiper:npm install [email protected] --save-dev 完成之後,你會在專案的node_modules資料夾中多一個swiper資料夾。 第二步:引用元件 import Swiper from 'swiper