scale_page_view 1.0.3

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 64

ScalePageView

一个将相邻的Page进行缩放到同一个屏显示的控件,可以用来做以下用途:

  1. 图片浏览
  2. 单页的 Tab
  3. 添加作为PageView标题栏
  4. (TODO) 可以修改加入无限滚动和轮播功能,变成轮播图

效果图

<img src="http://qiniu.inrush.me/2018-08-14-imageDemo.png" width=286 /><img src="http://qiniu.inrush.me/2018-08-14-textImage.png" width=286 />

第一张图是将图片进行分页 第二张图是将文字进行分页

GIF

可能会有点卡,GitHub显示不出来,可以到这里看gif

使用

Flutter Pub

Add this to your package's pubspec.yaml file:

dependencies:
  scale_page_view: ^1.0.3

You can install packages from the command line:

$ flutter packages get

Now in your Dart code, you can use:

import 'package:scale_page_view/scale_page_view.dart';
可用属性:
/// PageController
controller,
/// Page children
@required this.children,
/// type: ValueChanged<double> 
/// 页面滚动时触发,接收参数为 pageController.position.pixels
onPageChanging,
/// type: ValueChanged<int>
/// 页面变化时触发,接收的参数为改变后的新页面
onPageChange,
/// 当前页点击回调
onCurrentTabTap,
/// type: List<Widget>
/// 每一页的背景,length 必须等于 children.length
backgrounds,
/// type: Widget
/// 统一设置每一页的背景
background,
/// 设置是否显示指示器
indicator: true,
/// 设置指示器的颜色
indicatorColor: Colors.black,
/// 相邻的Page点击的时候是否要跳转
pageTapChange: true,
/// 当前页占屏幕宽度比例
pageRatio: 0.5,
/// 未选中页的缩放比,影响页面之间的间距
scaleRatio: 0.2,
/// 相邻页面的不透明度
opacityRatio: 0.5,
/// 页面的上下的Padding
paddingTB: 23.0

new Container(
    height: 200.0,
    child: new ScalePageView(
        key: _pageKey,
        children: images,
        backgrounds: backgrounds,
        onPageChanging: (value) {
            if (_pageController.position.pixels != value) {
                // _pageController 为另外一个PageView的Controller
                // 这样可以使ScalePageView移动的时候,另外一个PageView跟着动
                // 若要两个联动,可在另外一个PageView中添加NotificationListener,
                // 监听另外一个PageView滚动,然后通过GlobalKey<ScalePageViewState>,即上面设置的_pageKey,
                // 调用 _pageKey.currentState.jumpToWithoutSettling(
                // _pageController.position.pixels) 进行联动
                // 详细的实现请看 example 中的例子
                 _pageController.position.jumpToWithoutSettling(value);
            }
        },
        indicatorColor: Colors.white,
        pageRatio: 0.7,
        scaleRatio: 0.1,
        indicator: false,
        onPageChange: (index) {},
))

主要特性

  1. 在一屏中可以看到相邻两屏的内容
  2. 可以设置Widget作为背景
  3. 可以设置一屏的占比,相邻两屏的透明度以及缩放比
  4. 可以和其他PageView进行联动
  5. 内置一个横线作为指示器

TODO

  1. 设置无限循环滚动
  2. 加入轮播功能,可替代作为轮播图

参考

Official Example - Flutter Gallery

Realank/flutter_card_navi

[0.0.1] - The first release.

Features

  • Scale Multiple Page At One Page.

[1.0.0] - Official release.

No Change

[1.0.1] - (Minor edits) Add Property

add ScrollPhysics property

[1.0.2] - (Minor edits) Fix bug

fix example recreate bug

[1.0.3] - (Minor edits) Fix bug

  • fix pageTapChange invalid bug
  • delete pageTapOffset attributes

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:scale_page_view/scale_page_view.dart';

void main() {
  MaterialPageRoute.debugEnableFadingRoutes = true;
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Widget _buildItem(String name, WidgetBuilder builder) {
    return new ListTile(
      title: new GestureDetector(
        onTap: () {
          Navigator.of(context).push(new MaterialPageRoute(builder: builder));
        },
        child: new Text(name),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("ScalePageView"),
        elevation: 0.5,
      ),
      body: new ListView(
        children: <Widget>[
          new Divider(),
          _buildItem("Example1 Image Page View", (context) {
            return new Example1();
          }),
          new Divider(),
          _buildItem("Example2 Text Page View", (context) {
            return new Example2();
          }),
          new Divider(),
        ],
      ),
    );
  }
}

const double _kBar1Height = 300.0;
const double _kBar2Height = 100.0;

List<Widget> images = [
  new Image.network(
    "https://petbird.tw/wp-content/uploads/2013/06/pet105.jpg",
  ),
  new Image.network(
    "https://petbird.tw/wp-content/uploads/2013/06/pet105.jpg",
  ),
  new Image.network(
    "https://petbird.tw/wp-content/uploads/2013/06/pet105.jpg",
  ),
  new Image.network(
    "https://petbird.tw/wp-content/uploads/2013/06/pet105.jpg",
  ),
  new Image.network(
    "https://petbird.tw/wp-content/uploads/2013/06/pet105.jpg",
  ),
];

Widget _buildBackground(Color leftColor, Color rightColor) {
  return new Container(
    decoration: new BoxDecoration(
      gradient: new LinearGradient(
        begin: Alignment.centerLeft,
        end: Alignment.centerRight,
        colors: <Color>[
          leftColor,
          rightColor,
        ],
      ),
    ),
  );
}

List<Widget> backgrounds = [
  _buildBackground(const Color(0xFF3B5F8F), const Color(0xFF8266D4)),
  _buildBackground(const Color(0xFF8266D4), const Color(0xFFF95B57)),
  _buildBackground(const Color(0xFFF95B57), const Color(0xFFF3A646)),
  _buildBackground(const Color(0xFFF3A646), const Color(0xFF3B5F8F)),
  _buildBackground(const Color(0xFF3B5F8F), const Color(0xFF8266D4)),
];
const TextStyle sectionTitleStyle = const TextStyle(
  fontFamily: 'Raleway',
  inherit: false,
  fontSize: 20.0,
  fontWeight: FontWeight.w500,
  color: Colors.white,
  textBaseline: TextBaseline.alphabetic,
);
List<String> texts = [
  "西伯利亚雪橇犬",
  "西伯利亚雪橇犬",
  "西伯利亚雪橇犬",
  "西伯利亚雪橇犬",
  "西伯利亚雪橇犬",
];
List<String> descs = [
  "       西伯利亚雪橇犬(俄语:Сибирский хаски,英语:Siberian husky),常见别名哈士奇,昵称为二哈。西伯利亚雪橇犬体重介于雄犬20-27公斤,雌犬16-23公斤,身高大约雄犬肩高53-58厘米,雌犬51-56厘米,是一种中型犬。\n       西伯利亚雪橇犬是原始的古老犬种,在西伯利亚东北部、格陵兰南部生活。哈士奇名字的由来,是源自其独特的嘶哑声。哈士奇性格多变,有的极端胆小,也有的极端暴力,进入大陆和家庭的哈士奇,都已经没有了这种极端的性格,比较温顺,是一种流行于全球的宠物犬。与金毛犬、拉布拉多并列为三大无攻击型犬类。被世界各地广泛饲养,并在全球范围内,有大量该犬种的赛事。",
  "       西伯利亚雪橇犬(俄语:Сибирский хаски,英语:Siberian husky),常见别名哈士奇,昵称为二哈。西伯利亚雪橇犬体重介于雄犬20-27公斤,雌犬16-23公斤,身高大约雄犬肩高53-58厘米,雌犬51-56厘米,是一种中型犬。\n       西伯利亚雪橇犬是原始的古老犬种,在西伯利亚东北部、格陵兰南部生活。哈士奇名字的由来,是源自其独特的嘶哑声。哈士奇性格多变,有的极端胆小,也有的极端暴力,进入大陆和家庭的哈士奇,都已经没有了这种极端的性格,比较温顺,是一种流行于全球的宠物犬。与金毛犬、拉布拉多并列为三大无攻击型犬类。被世界各地广泛饲养,并在全球范围内,有大量该犬种的赛事。",
  "       西伯利亚雪橇犬(俄语:Сибирский хаски,英语:Siberian husky),常见别名哈士奇,昵称为二哈。西伯利亚雪橇犬体重介于雄犬20-27公斤,雌犬16-23公斤,身高大约雄犬肩高53-58厘米,雌犬51-56厘米,是一种中型犬。\n       西伯利亚雪橇犬是原始的古老犬种,在西伯利亚东北部、格陵兰南部生活。哈士奇名字的由来,是源自其独特的嘶哑声。哈士奇性格多变,有的极端胆小,也有的极端暴力,进入大陆和家庭的哈士奇,都已经没有了这种极端的性格,比较温顺,是一种流行于全球的宠物犬。与金毛犬、拉布拉多并列为三大无攻击型犬类。被世界各地广泛饲养,并在全球范围内,有大量该犬种的赛事。",
  "       西伯利亚雪橇犬(俄语:Сибирский хаски,英语:Siberian husky),常见别名哈士奇,昵称为二哈。西伯利亚雪橇犬体重介于雄犬20-27公斤,雌犬16-23公斤,身高大约雄犬肩高53-58厘米,雌犬51-56厘米,是一种中型犬。\n       西伯利亚雪橇犬是原始的古老犬种,在西伯利亚东北部、格陵兰南部生活。哈士奇名字的由来,是源自其独特的嘶哑声。哈士奇性格多变,有的极端胆小,也有的极端暴力,进入大陆和家庭的哈士奇,都已经没有了这种极端的性格,比较温顺,是一种流行于全球的宠物犬。与金毛犬、拉布拉多并列为三大无攻击型犬类。被世界各地广泛饲养,并在全球范围内,有大量该犬种的赛事。",
  "       西伯利亚雪橇犬(俄语:Сибирский хаски,英语:Siberian husky),常见别名哈士奇,昵称为二哈。西伯利亚雪橇犬体重介于雄犬20-27公斤,雌犬16-23公斤,身高大约雄犬肩高53-58厘米,雌犬51-56厘米,是一种中型犬。\n       西伯利亚雪橇犬是原始的古老犬种,在西伯利亚东北部、格陵兰南部生活。哈士奇名字的由来,是源自其独特的嘶哑声。哈士奇性格多变,有的极端胆小,也有的极端暴力,进入大陆和家庭的哈士奇,都已经没有了这种极端的性格,比较温顺,是一种流行于全球的宠物犬。与金毛犬、拉布拉多并列为三大无攻击型犬类。被世界各地广泛饲养,并在全球范围内,有大量该犬种的赛事。",
];

class Example1 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new Example1State();
  }
}

/// Use State,avoid reinitializing variables because of refresh
class Example1State extends State<Example1> {
  final PageController _pageController = new PageController();
  final PageController _tabController = new PageController();

  @override
  Widget build(BuildContext context) {
    return new Material(
      child: new Column(
        children: <Widget>[
          new Container(
              height: _kBar1Height,
              child: new ScalePageView(
                controller: _tabController,
                children: images,
                pageTapChange: true,
//              backgrounds: backgrounds,
                onPageChanging: (value) {
                  if (_pageController.position.pixels != value) {
                    _pageController.position.jumpToWithoutSettling(value);
                  }
                },
                onCurrentTabTap: (index){
                  debugPrint("touch $index");
                },
                indicatorColor: Colors.white,
                pageRatio: 0.7,
                scaleRatio: 0.1,
                indicator: false,
                onPageChange: (index) {},
              )),
          new Expanded(
              child: new NotificationListener(
                  onNotification: (notification) {
                    if (notification is ScrollUpdateNotification) {
                      if (_tabController.position.pixels !=
                          _pageController.position.pixels) {
                        _tabController.position.jumpToWithoutSettling(
                            _pageController.position.pixels);
                      }
                    }
                  },
                  child: new PageView.builder(
                    controller: _pageController,
                    itemBuilder: (context, index) {
                      return new Container(
                          color: Colors.white,
                          padding: const EdgeInsets.all(20.0),
                          child: new SingleChildScrollView(
                            child: new Column(
                              children: <Widget>[
                                new Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: <Widget>[
                                    new Text(
                                      texts[index],
                                      style: new TextStyle(
                                          fontSize: 23.0,
                                          color: Color(0xff333333)),
                                    )
                                  ],
                                ),
                                new Padding(
                                  padding: const EdgeInsets.only(top: 20.0),
                                  child: new RichText(
                                    text: new TextSpan(
                                        text: descs[index],
                                        style: new TextStyle(
                                            fontSize: 18.0,
                                            color: Color(0xff999999))),
                                  ),
                                )
                              ],
                            ),
                          ));
                    },
                    itemCount: images.length,
                  )))
        ],
      ),
    );
  }
}

class Example2 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new Example2State();
  }
}

class Example2State extends State<Example2> {
  final PageController _pageController = new PageController();
  final PageController _tabController = new PageController();

  @override
  Widget build(BuildContext context) {
    return new Material(
      child: new Column(
        children: <Widget>[
          new Container(
              height: _kBar2Height,
              child: new ScalePageView(
                controller: _tabController,
                children: texts.map((String text) {
                  return new Text(
                    text,
                    style: sectionTitleStyle,
                  );
                }).toList(),
                backgrounds: backgrounds,
                onPageChanging: (value) {
                  if (_pageController.position.pixels != value) {
                    _pageController.position.jumpToWithoutSettling(value);
                  }
                },
                indicatorColor: Colors.white,
                pageRatio: 0.5,
                scaleRatio: 0.3,
                indicator: true,
                onPageChange: (index) {},
              )),
          new Expanded(
              child: new NotificationListener(
                  onNotification: (notification) {
                    if (notification is ScrollUpdateNotification) {
                      if (_tabController.position.pixels !=
                          _pageController.position.pixels) {
                        _tabController.position.jumpToWithoutSettling(
                            _pageController.position.pixels);
                      }
                    }
                  },
                  child: new PageView.builder(
                    controller: _pageController,
                    itemBuilder: (context, index) {
                      return new Container(
                        color: Colors.white,
                        padding: const EdgeInsets.all(20.0),
                        child: new SingleChildScrollView(
                          child: new Column(
                            children: <Widget>[
                              new Padding(
                                padding: const EdgeInsets.only(top: 20.0),
                                child: images[index],
                              ),
                              new Padding(
                                padding: const EdgeInsets.only(top: 20.0),
                                child: new RichText(
                                  text: new TextSpan(
                                      text: descs[index],
                                      style: new TextStyle(
                                          fontSize: 18.0,
                                          color: Color(0xff999999))),
                                ),
                              )
                            ],
                          ),
                        ),
                      );
                    },
                    itemCount: images.length,
                  )))
        ],
      ),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  scale_page_view: ^1.0.3

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:scale_page_view/scale_page_view.dart';
  
Version Uploaded Documentation Archive
1.0.3 Sep 1, 2018 Go to the documentation of scale_page_view 1.0.3 Download scale_page_view 1.0.3 archive
1.0.2 Aug 17, 2018 Go to the documentation of scale_page_view 1.0.2 Download scale_page_view 1.0.2 archive
1.0.1 Aug 15, 2018 Go to the documentation of scale_page_view 1.0.1 Download scale_page_view 1.0.1 archive
1.0.0 Aug 15, 2018 Go to the documentation of scale_page_view 1.0.0 Download scale_page_view 1.0.0 archive
0.0.1 Aug 14, 2018 Go to the documentation of scale_page_view 0.0.1 Download scale_page_view 0.0.1 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
37
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
80
Overall:
Weighted score of the above. [more]
64
Learn more about scoring.

We analyzed this package on Sep 18, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0
  • pana: 0.12.3
  • Flutter: 0.8.4

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Suggestions

The description is too short.

Add more detail about the package, what it does and what is its target use case. Try to write at least 60 characters.

Fix lib/scale_page_view.dart.

Analysis of lib/scale_page_view.dart reported 1 hint:

line 4 col 8: Unused import: 'dart:math'.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.28.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11
meta 1.1.6
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test