nine_grid_view 1.0.5

  • Readme
  • Changelog
  • Example
  • Installing
  • new66

Language: English | 中文简体

Pub      Pub

NineGridView #

Similar to Weibo dynamics, WeChat circle of friends, nine grid view controls to display pictures. Support single big picture preview.
It also supports WeChat group , DingTalk group, QQ group avatar effects.

DragSortView #

Similar to Weibo/WeChat release dynamic picture selection nine grid view. Support press to enlarge effect, drag and drop sorting, drag and drop to a specified location to delete.

Pub #

dependencies:
  nine_grid_view: ^1.0.5

Example #

import 'package:nine_grid_view/nine_grid_view.dart';

// bigImage param, It is recommended to use a medium-quality picture, because the original picture is too large and takes time to load.
NineGridView(
  margin: EdgeInsets.all(12),
  padding: EdgeInsets.all(5),
  space: 5,
  type: NineGridType.weChatGp,
  itemCount: itemCount,
  itemBuilder: (BuildContext context, int index) {},
);

// It is recommended to use a thumbnail picture,because the original picture is too large, it may cause repeated loading and cause flashing.
DragSortView(
  imageList,
  space: 5,
  margin: EdgeInsets.all(20),
  padding: EdgeInsets.all(0),
  itemBuilder: (BuildContext context, int index) {},
  initBuilder: (BuildContext context) {},
  onDragListener: (MotionEvent event, double itemWidth) {
    /// Judge to drag to the specified position to delete
    /// return true;
    if (event.globalY > 600) {
      return true;
    }
    return false;
  },
);   

Screenshots #

App #

A Weibo client app developed with Flutter Fitness
Apk :v0.0.3 (arm64-v8a)

Others #

Another NineGridView in flukit UI Kit,using GridView implementation。But in this project used Stack + Positioned。

1.0.5 #

  • TODO: space param support QQ Group.

1.0.3 #

  • TODO: add QQ Group avatar effects.

1.0.2 #

  • TODO: fix bug.

1.0.1 #

  • TODO: add license.

1.0.0 #

  • TODO: NineGridView & DragSortView.

example/lib/main.dart

import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:nine_grid_view/nine_grid_view.dart';
import 'package:nine_grid_view_example/drag_sort_page.dart';
import 'package:nine_grid_view_example/models.dart';
import 'package:nine_grid_view_example/single_picture_page.dart';
import 'package:nine_grid_view_example/utils.dart';

void main() {
  runApp(MyApp());
  if (Platform.isAndroid) {
    SystemChrome.setSystemUIOverlayStyle(
        SystemUiOverlayStyle(statusBarColor: Colors.transparent));
  }
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _title = 'QQ Group';

  NineGridType _gridType = NineGridType.qqGp;

  List<ImageBean> imageList = List();

  @override
  void initState() {
    super.initState();
    imageList = Utils.getTestData();
  }

  Widget _buildItem(BuildContext context, int _index) {
    int itemCount = _index % 9 + 1;
    if (_gridType == NineGridType.normal ||
        _gridType == NineGridType.weiBo ||
        _gridType == NineGridType.weChat) {
      return Container(
        decoration: BoxDecoration(
            border: Border(
                bottom: BorderSide(width: 0.33, color: Color(0xffe5e5e5)))),
        padding: EdgeInsets.all(0),
        child: NineGridView(
          margin: EdgeInsets.all(12),
          padding: EdgeInsets.all(5),
          space: 5,
          type: _gridType,
          color: Color(0XFFE5E5E5),
          itemCount: itemCount,
          itemBuilder: (BuildContext context, int index) {
            ImageBean bean = imageList[index];
            return Utils.getWidget(bean.middlePath);
          },
        ),
      );
    }
    itemCount = (_index % (_gridType == NineGridType.dingTalkGp ? 4 : 9) + 1);
    Decoration decoration = BoxDecoration(
      color: Color(0XFFE5E5E5),
      shape: BoxShape.rectangle,
      borderRadius: BorderRadius.all(Radius.circular(4)),
    );
    Widget header = NineGridView(
      width: 120,
      height: 120,
      padding: EdgeInsets.all(2),
      alignment: Alignment.center,
      space: 3,
      type: _gridType,
      decoration: _gridType == NineGridType.weChatGp ? decoration : null,
      itemCount: itemCount,
      itemBuilder: (BuildContext context, int index) {
        ImageBean bean = imageList[index];
        return Utils.getWidget(bean.middlePath);
      },
    );

    return InkWell(
      onTap: () {},
      child: Container(
        padding: EdgeInsets.only(left: 12, top: 12, right: 12, bottom: 12),
        decoration: BoxDecoration(
            border: Border(
                bottom: BorderSide(width: 0.33, color: Color(0xffe5e5e5)))),
        child: Row(
          children: <Widget>[header],
        ),
      ),
    );
  }

  Widget _buildGroup(BuildContext context) {
    Decoration decoration = BoxDecoration(
      color: Color(0XFFE5E5E5),
      shape: BoxShape.rectangle,
      borderRadius: BorderRadius.all(Radius.circular(4)),
    );
    int total;
    switch (_gridType) {
      case NineGridType.qqGp:
        total = 5;
        break;
      case NineGridType.weChatGp:
        total = 9;
        break;
      case NineGridType.dingTalkGp:
        total = 4;
        break;
    }
    List<Widget> children = List();
    for (int i = 0; i < 9; i++) {
      children.add(NineGridView(
        width: (MediaQuery.of(context).size.width - 60) / 3,
        height: (MediaQuery.of(context).size.width - 60) / 3,
        padding: EdgeInsets.all(2),
        margin: EdgeInsets.all(5),
        alignment: Alignment.center,
        space: 3,
        //arcAngle: 60,
        type: _gridType,
        decoration: _gridType == NineGridType.dingTalkGp ? null : decoration,
        itemCount: i % total + 1,
        itemBuilder: (BuildContext context, int index) {
          ImageBean bean = imageList[index];
          return Utils.getWidget(bean.middlePath);
        },
      ));
    }
    return Wrap(
      alignment: WrapAlignment.center,
      children: children,
    );
  }

  void _onPopSelected(NineGridType value) {
    print('Sky24n _onPopSelected...... $value');
    if (_gridType != value) {
      _gridType = value;
      switch (value) {
        case NineGridType.qqGp:
          _title = 'QQ Group';
          break;
        case NineGridType.weChatGp:
          _title = 'WeChat Group';
          break;
        case NineGridType.dingTalkGp:
          _title = 'DingTalk Group';
          break;
        case NineGridType.weChat:
          _title = 'WeChat';
          break;
        case NineGridType.weiBo:
          _title = 'WeiBo Intl';
          break;
        case NineGridType.normal:
          _title = 'Normal';
          break;
      }
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('$_title'),
        centerTitle: true,
        actions: <Widget>[
          PopupMenuButton(
              icon: Icon(Icons.settings),
              padding: const EdgeInsets.all(0.0),
              onSelected: _onPopSelected,
              itemBuilder: (BuildContext context) =>
                  <PopupMenuItem<NineGridType>>[
                    PopupMenuItem<NineGridType>(
                        value: NineGridType.qqGp,
                        child: ListTile(
                            contentPadding: EdgeInsets.all(0.0),
                            dense: false,
                            title: Text(
                              'QQ Group',
                            ))),
                    PopupMenuItem<NineGridType>(
                        value: NineGridType.weChatGp,
                        child: ListTile(
                            contentPadding: EdgeInsets.all(0.0),
                            dense: false,
                            title: Text(
                              'WeChat Group',
                            ))),
                    PopupMenuItem<NineGridType>(
                        value: NineGridType.dingTalkGp,
                        child: ListTile(
                            contentPadding: EdgeInsets.all(0.0),
                            dense: false,
                            title: Text(
                              'DingTalk Group',
                            ))),
                    PopupMenuItem<NineGridType>(
                        value: NineGridType.weChat,
                        child: ListTile(
                            contentPadding: EdgeInsets.all(0.0),
                            dense: false,
                            title: Text(
                              'WeChat',
                            ))),
                    PopupMenuItem<NineGridType>(
                        value: NineGridType.weiBo,
                        child: ListTile(
                            contentPadding: EdgeInsets.all(0.0),
                            dense: false,
                            title: Text(
                              'WeiBo',
                            ))),
                    PopupMenuItem<NineGridType>(
                        value: NineGridType.normal,
                        child: ListTile(
                            contentPadding: EdgeInsets.all(0.0),
                            dense: false,
                            title: Text(
                              'Normal',
                            ))),
                    PopupMenuItem<NineGridType>(
                        value: NineGridType.normal,
                        child: ListTile(
                          contentPadding: EdgeInsets.all(0.0),
                          dense: false,
                          title: Text(
                            'Single Picture',
                          ),
                          onTap: () {
                            Utils.pushPage(context, SinglePicturePage());
                          },
                        )),
                  ]),
        ],
      ),
      body: (_gridType == NineGridType.qqGp ||
              _gridType == NineGridType.weChatGp ||
              _gridType == NineGridType.dingTalkGp)
          ? ListView(
              physics: AlwaysScrollableScrollPhysics(
                  parent: BouncingScrollPhysics()),
              children: <Widget>[
                SizedBox(height: 15),
                _buildGroup(context),
                Offstage(
                  offstage: _gridType != NineGridType.qqGp,
                  child: QQGroup(),
                ),
              ],
            )
          : ListView.builder(
              physics: BouncingScrollPhysics(),
              itemCount: 9,
              padding: EdgeInsets.all(0),
              itemBuilder: (BuildContext context, int index) {
                return _buildItem(context, index);
              }),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Utils.pushPage(context, DragSortPage());
        },
        child: Icon(Icons.camera_alt),
      ),
    );
  }
}

class QQGroup extends StatefulWidget {
  @override
  _QQGroupState createState() => _QQGroupState();
}

class _QQGroupState extends State<QQGroup> with TickerProviderStateMixin {
  AnimationController _controller;
  List<ImageBean> imageList = List();

  @override
  void initState() {
    super.initState();
    imageList = Utils.getTestData();
    _controller = AnimationController(
        duration: Duration(milliseconds: 2000), vsync: this);
    _controller.addListener(() {
      setState(() {});
    });
    _controller.repeat(reverse: true);
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: NineGridView(
        width: 200,
        height: 200,
        arcAngle: (_controller.value * 180).round().toDouble(),
        type: NineGridType.qqGp,
        itemCount: 5,
        itemBuilder: (BuildContext context, int index) {
          ImageBean bean = imageList[index];
          return Utils.getWidget(bean.middlePath);
        },
      ),
    );
  }
}

Use this package as a library

1. Depend on it

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


dependencies:
  nine_grid_view: ^1.0.5

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

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

3. Import it

Now in your Dart code, you can use:


import 'package:nine_grid_view/nine_grid_view.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
33
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
66
Learn more about scoring.

We analyzed this package on Jul 14, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.15
  • Flutter: 1.17.5

Analysis suggestions

Package not compatible with SDK dart

Because:

  • nine_grid_view that is a package requiring null.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.12 1.14.13
meta 1.1.8 1.2.2
sky_engine 0.0.99
typed_data 1.1.6 1.2.0
vector_math 2.0.8 2.1.0-nullsafety
Dev dependencies
flutter_test