Flutter banner輪播圖之Swiper

輪播圖簡直是不要太常見的功能了。今天來看一下在Flutter中是怎麼實現的。

效果
在這裏插入圖片描述

關於Swiper

flutter最強大的siwiper, 多種佈局方式,無限輪播,Android和IOS雙端適配.
github:https://github.com/best-flutter/flutter_swiper

引用:

flutter_swiper : ^1.1.6

示例並講解

廢話不多說,直接拿效果圖講解。
在這裏插入圖片描述

注意看上圖中紅色標記的部分:

  • 1,分頁控制器,即點擊到下一頁或上一頁,效果等於觸摸滑動
  • 2,不顯示的item在兩側縮小顯示
  • 3,指示器中,選中的要偏大一些

ok,圍繞着基礎使用 擴展一些常見的功能。


基礎使用

            child: Swiper(
              itemCount: bannerDatas.length,
              //item數量
              itemBuilder: (BuildContext context, int index) {
                //item構建
                return new Image.network(
                  "https://www.wanandroid.com/blogimgs/acc23063-1884-4925-bdf8-0b0364a7243e.png",
                  fit: BoxFit.fill,
                );
              },
            ),

基礎使用兩個參數就行了,

  • itemCount: item數量
  • itemBuilder: item構建

分頁控制器

這個其實一般用的不多。。

添加一個control屬性即可

control: new SwiperControl(),//默認分頁按鈕

看一下源碼:

  const SwiperControl(
      {this.iconPrevious: Icons.arrow_back_ios,
      this.iconNext: Icons.arrow_forward_ios,
      this.color,
      this.disableColor,
      this.key,
      this.size: 30.0,
      this.padding: const EdgeInsets.all(5.0)});

可以修改圖標、顏色、大小等等,比如

control: new SwiperControl(size: 20),

顯示樣式

效果圖中可以看出,不顯示的item是在兩側縮小顯示的,那這種樣式怎麼實現呢?

添加兩個參數

viewportFraction: 0.8,
scale: 0.9,
  • viewportFraction:視圖寬度,即顯示的item的寬度屏佔比
  • scale:兩側item的縮放比

參數在0到1之間。


指示器

pagination: new SwiperPagination(),//默認指示器

默認即圓點的方式,
其他樣式:

class SwiperPagination extends SwiperPlugin {
  /// dot style pagination
  static const SwiperPlugin dots = const DotSwiperPaginationBuilder();

  /// fraction style pagination
  static const SwiperPlugin fraction = const FractionPaginationBuilder();

  static const SwiperPlugin rect = const RectSwiperPaginationBuilder();

....
}

上面源碼可以看到,SwiperPagination 繼承自SwiperPlugin

然後 dots 其實是 DotSwiperPaginationBuilder,DotSwiperPaginationBuilder也是繼承自SwiperPlugin


進一步查看源碼:

class DotSwiperPaginationBuilder extends SwiperPlugin {
  
  .....
  
  const DotSwiperPaginationBuilder(
      {this.activeColor,
      this.color,
      this.key,
      this.size: 10.0,
      this.activeSize: 10.0,
      this.space: 3.0});
....

我們可以看到顏色和大小都有選中和未選中之分,還可以設置間距,那我們就可以輕鬆的實現上圖中的效果了

              pagination: new SwiperPagination( 
                builder: new DotSwiperPaginationBuilder(size: 8, activeSize: 12),
              ),

只簡單改一下size就ok了


點擊事件

onTap,接收一個下標參數:

              onTap: (int index) {
                //點擊事件,返回下標
                print("index-----" + index.toString());
              },

高度自適應

如何做到banner高度自適應呢,目前的解決方案就是動態計算。
外層用Container包裹,然後設置Container的寬高。

          Container(
          
            //屏幕寬度
            width: MediaQuery.of(context).size.width,
            //1.8是banner寬高比,0.8是viewportFraction的值
            height: MediaQuery.of(context).size.width / 1.8 * 0.8,
            
            child: Swiper(
             ...
            ),
          ),

完整代碼

          Container(
            width: MediaQuery.of(context).size.width,
            //1.8是banner寬高比,0.8是viewportFraction的值
            height: MediaQuery.of(context).size.width / 1.8 * 0.8,
            child: Swiper(
              itemCount: bannerDatas.length,
              //item數量
              itemBuilder: (BuildContext context, int index) {
                //item構建
                return new Image.network(
                  bannerDatas[index].imagePath,
                  fit: BoxFit.fill,
                );
              },
              autoplay: true,
              //是否自動播放
              autoplayDelay: 3000,
              //自動播放延遲
              autoplayDisableOnInteraction: true,
              //觸發時是否停止播放

              duration: 600,
              //動畫時間

              control: new SwiperControl(),
              //默認分頁按鈕

              //默認指示器
              pagination: new SwiperPagination(
                // SwiperPagination.fraction 數字1/5,默認點
                builder: new DotSwiperPaginationBuilder(size: 8, activeSize: 12),
              ),

              viewportFraction: 0.8,
              //視圖寬度,即顯示的item的寬度屏佔比
              scale: 0.9,
              //兩側item的縮放比

              onTap: (int index) {
                //點擊事件,返回下標
                print("index-----" + index.toString());
              },
            ),
          ),

Github:https://github.com/yechaoa/wanandroid_flutter


swiper 嵌套在listview(scrollview)中 的時候會報ScrollController not attached to any scroll views.異常,還未解決,解決的還請告知一下


詳細屬性

基本參數

參數 默認值 描述
scrollDirection Axis.horizontal 滾動方向,設置爲Axis.vertical如果需要垂直滾動
loop true 無限輪播模式開關
index 0 初始的時候下標位置
autoplay false 自動播放開關.
onIndexChanged void onIndexChanged(int index) 當用戶手動拖拽或者自動播放引起下標改變的時候調用
onTap void onTap(int index) 當用戶點擊某個輪播的時候調用
duration 300.0 動畫時間,單位是毫秒
pagination null 設置 new SwiperPagination() 展示默認分頁指示器
control null 設置 new SwiperControl() 展示默認分頁按鈕
autoplayDely 3000 自動播放延遲毫秒數.
autoplayDisableOnInteraction true 當用戶拖拽的時候,是否停止自動播放.

分頁指示器

分頁指示器繼承自 SwiperPlugin,SwiperPluginSwiper 提供額外的界面.設置爲new SwiperPagination() 展示默認分頁.

參數 默認值 描述
alignment Alignment.bottomCenter 如果要將分頁指示器放到其他位置,那麼可以修改這個參數
margin const EdgeInsets.all(10.0) 分頁指示器與容器邊框的距離
builder SwiperPagination.dots 目前已經定義了兩個默認的分頁指示器樣式: SwiperPagination.dotsSwiperPagination.fraction,都可以做進一步的自定義.

如果需要定製自己的分頁指示器,那麼可以這樣寫:

new Swiper(
    ...,
    pagination:new SwiperCustomPagination(
        builder:(BuildContext context, SwiperPluginConfig config){
            return new YourOwnPaginatipon();
        }
    )
);


控制按鈕

控制按鈕組件也是繼承自 SwiperPlugin,設置 new SwiperControl() 展示默認控制按鈕.

參數 默認值 描述
iconPrevious Icons.arrow_back_ios 上一頁的IconData
iconNext Icons.arrow_forward_ios 下一頁的IconData
color Theme.of(context).primaryColor 控制按鈕顏色
size 30.0 控制按鈕的大小
padding const EdgeInsets.all(5.0) 控制按鈕與容器的距離

控制器(SwiperController)

SwiperController 用於控制 Swiper的index屬性, 停止和開始自動播放. 通過 new SwiperController() 創建一個SwiperController實例,並保存,以便將來能使用。

方法 描述
void move(int index, {bool animation: true}) 移動到指定下標,設置是否播放動畫
void next({bool animation: true}) 下一頁
void previous({bool animation: true}) 上一頁
void startAutoplay() 開始自動播放
void stopAutoplay() 停止自動播放

構建你自己的動畫十分簡單:


 new Swiper(
  layout: SwiperLayout.CUSTOM,
  customLayoutOption: new CustomLayoutOption(
      startIndex: -1,
      stateCount: 3
  ).addRotate([
    -45.0/180,
    0.0,
    45.0/180
  ]).addTranslate([
    new Offset(-370.0, -40.0),
    new Offset(0.0, 0.0),
    new Offset(370.0, -40.0)
  ]),
  itemWidth: 300.0,
  itemHeight: 200.0,
  itemBuilder: (context, index) {
    return new Container(
      color: Colors.grey,
      child: new Center(
        child: new Text("$index"),
      ),
    );
  },
  itemCount: 10)


CustomLayoutOption 被設計用來描述佈局和動畫,很簡單的可以指定每一個元素的狀態.

new CustomLayoutOption(
      startIndex: -1,  /// 開始下標
      stateCount: 3    /// 下面的數組長度 
  ).addRotate([        //  每個元素的角度
    -45.0/180,
    0.0,
    45.0/180
  ]).addTranslate([           /// 每個元素的偏移
    new Offset(-370.0, -40.0),
    new Offset(0.0, 0.0),
    new Offset(370.0, -40.0)
  ])



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