Flutter仿微信朋友圈动态

先看一下效果图吧。

微信截图_20190726163636.png

其实没有实现难点,直接通过网络请求获取到动态数据,图片链接就在获取到的数据中,直接使用ListView,然后定义一下item布局和数据,图片展示直接用的三目表达式,单个图片使用Image,多个图片使用GridView。

先来第一步,获取网络数据。想要网络数据首先要进行网络访问,我使用的是dio库,链接如下:


dio: 2.1.13#网络

网络请求就不写了,很简单,大家直接百度一大堆。

然后第二步,创建ListView,为了代码清晰,我把ListView放在了另一个dart文件中,其中也实现了下拉刷新和上拉加载功能,下面是ListView的详细代码。


import 'dart:convert';

import 'package:dio/dio.dart';

import 'package:flutter/cupertino.dart';

import 'package:flutter/material.dart';

import 'package:flutter_learning/bean/dynamicbean_entity.dart';

import 'package:flutter_learning/utils/http.dart';

import 'package:flutter_learning/utils/toast.dart';

import 'package:flutter_learning/utils/viewpicture.dart';

import 'package:flutter_screenutil/flutter_screenutil.dart';

class projectitemextends StatefulWidget {

Listdynamicbean;

  projectitem(List dynamicbean) {

this.dynamicbean = dynamicbean;

  }

@override

  StatecreateState() {

// TODO: implement createState

    return itemBuild();

  }

}

class itemBuildextends State {

//初始化滚动监听器,加载更多使用

  intpages =1;

  ScrollController_controller =new ScrollController();

  StringloadMoreText ="没有更多数据";

  TextStyleloadMoreTextStyle =

new TextStyle(color:const Color(0xFF999999), fontSize:14.0);

  @override

  Widgetbuild(BuildContext context) {

// TODO: implement build

    return Container(

child:RefreshIndicator(

child:ListView.builder(

//physics: NeverScrollableScrollPhysics(),

            shrinkWrap:true,

            itemCount:widget.dynamicbean.length,

            itemBuilder: (BuildContext context, int position) {

return getItem(widget.dynamicbean[position]);

            },

            controller:_controller,

          ),

          onRefresh: _refresh),

    );

  }

Future_refresh()async {

_controller.addListener(() {

/*var maxScroll = _controller.position.maxScrollExtent;

var pixel = _controller.position.pixels;*/

      load(++pages,"");

        setState(() {

loadMoreText ="正在加载中...";

          loadMoreTextStyle =

new TextStyle(color:const Color(0xFF4483f6), fontSize:14.0);

        });

    });

    load(1, "");

    return;

  }

//获取当前登录人的数据库信息

  void load(int page, String keyword)async {

if(page==1){

widget.dynamicbean.clear();

    }

Dio dio = http.getDio();

    var _result ="";

    try {

await dio

.get(

"dynamic/getDynamics?data={'page': '${page}','keyword': '${keyword}'}")

.then((responses) {

if (responses.statusCode ==200) {

_result = responses.data.toString();

          print(_result);

          /*先将字符串转成json*/

          Map json = jsonDecode(_result);

          /**/

//UserBean newsBean = UserBean.fromJson(json);

          DynamicbeanEntity dynamicbeanEntity =

DynamicbeanEntity.fromJson(json);

          if (dynamicbeanEntity.success) {

widget.dynamicbean.addAll(dynamicbeanEntity.rows);

            setState(() {});

          }

}else {

_result ='error code : ${responses.statusCode}';

        }

});

    }catch (exception) {

print('exc:$exception');

      _result ='网络异常';

    }

}

WidgetgetItem(DynamicbeanRow mData) {

return Card(

margin:EdgeInsets.all(10),

      child:InkWell(

onTap: () {

toast.showToasts(mData.name);

          /*Navigator.push(

context,

new MaterialPageRoute(builder: (context) => new map(mData)),

);*/

        },

        child:Container(

alignment: Alignment.topLeft,

          width: MediaQuery.of(context).size.width,

          padding:EdgeInsets.all(ScreenUtil().setHeight(20)),

          child:Column(

//mainAxisAlignment: MainAxisAlignment.start,  行里用这个

            crossAxisAlignment: CrossAxisAlignment.start, //列里用这个

            children: [

Container(

//显示用户名

                margin:EdgeInsets.all(1),

                child:Text(

mData.name,

                  style:TextStyle(color: Colors.blue, fontSize:16),

                ),

              ),

              Container(

//显示时间

                margin:EdgeInsets.all(1),

                child:Text(

mData.date,

                  style:TextStyle(color: Colors.black54, fontSize:14),

                ),

              ),

              Container(

//画一条线

                margin:EdgeInsets.all(1),

                child:Divider(

height:0.2,

                  indent:0,

                  color: Colors.black45,

                ),

              ),

              Container(

//显示内容

                margin:EdgeInsets.all(3),

                child:Text(

mData.content,

                  style:TextStyle(color: Colors.black87, fontSize:14),

                ),

              ),

              mData.urlList.length >0

                  ? mData.urlList.length ==1

                      ?Image.network(

mData.urlList[0],

                          width:ScreenUtil().setWidth(1000),

                          height:ScreenUtil().setHeight(1000),

                        )

:GridView.builder(

physics:NeverScrollableScrollPhysics(),

                          shrinkWrap:true,

                          itemCount: mData.urlList.length,

                          gridDelegate:

SliverGridDelegateWithFixedCrossAxisCount(

//横轴元素个数

                            crossAxisCount:3,

                            /*//纵轴间距mainAxisSpacing: 1.0,

                                  //横轴间距crossAxisSpacing: 1.0,

                                  //子组件宽高长度比例childAspectRatio: 1.4*/

                          ),

                          itemBuilder: (BuildContext context, int index) {

return InkWell(

onTap: () {

toast.showToasts("哈哈哈");

                                Navigator.of(context).push(   //点击显示类似朋友圈查看图片功能

NinePicture(mData.urlList, index), // 图片集合,要显示的下标

                                );

                              },

                              child:Container(

margin:EdgeInsets.all(1),

                                child:Image.network(mData.urlList[index]),

                              ),

                            );

                          },

                        )

:Container(),

            ],

          ),

        ),

      ),

    );

  }

}

对了,里面还实现了类似朋友圈点击图片查看图片的功能,该工具类如下,这位兄台写的工具类。


import 'package:flutter/material.dart';

class NinePictureextends PopupRoute {

final StringbarrierLabel;

  final ListpicList; //图片集合

  final intindex; //显示的图片下标

  intstartX;

  intendX;

  NinePicture(this.picList, this.index, {this.barrierLabel});

  @override

  Durationget transitionDuration =>Duration(milliseconds:2000);

  @override

@override

  Colorget barrierColor => Colors.black54;

  @override

  boolget barrierDismissible =>true;

  AnimationController_animationController;

  @override

  AnimationControllercreateAnimationController() {

assert(_animationController ==null);

    _animationController =

BottomSheet.createAnimationController(navigator.overlay);

    return _animationController;

  }

@override

  WidgetbuildPage(BuildContext context, Animation animation,

      Animation secondaryAnimation) {

return MediaQuery.removePadding(

removeTop:true,

      context: context,

      child:GestureDetector(

child:AnimatedBuilder(

animation: animation,

          builder: (BuildContext context, Widget child) =>GestureDetector(

onTap: () {

Navigator.pop(context);

            },

            child:_PictureWidget(picList, index),

          ),

        ),

      ),

    );

  }

}

class _PictureWidgetextends StatefulWidget {

final ListpicList;

  final intindex;

  _PictureWidget(this.picList, this.index);

  @override

  StatecreateState() {

return _PictureWidgetState();

  }

}

class _PictureWidgetStateextends State<_PictureWidget> {

intstartX =0;

  intendX =0;

  intindex =0;

  @override

  void initState() {

// TODO: implement initState

    super.initState();

    index =widget.index;

    print("全屏显示:${widget.picList}${widget.index}");

  }

@override

  Widgetbuild(BuildContext context) {

return new Material(

color: Colors.transparent,

      child:new Container(

width: double.infinity,

        child:Stack(

children: [

GestureDetector(

child:Center(

child:

Image.network(widget.picList[index])

/*CachedNetworkImage(

imageUrl: widget.picList[index],

fit: BoxFit.cover,

                )*/,

              ),

              onHorizontalDragDown: (detail) {

startX = detail.globalPosition.dx.toInt();

              },

              onHorizontalDragUpdate: (detail) {

endX = detail.globalPosition.dx.toInt();

              },

              onHorizontalDragEnd: (detail) {

_getIndex(endX -startX);

                setState(() {});

              },

              onHorizontalDragCancel: () {},

            ),

            Align(

alignment: Alignment.bottomCenter,

              child:Padding(

padding:const EdgeInsets.all(8.0),

                child:Row(

mainAxisAlignment: MainAxisAlignment.spaceAround,

                  children:List.generate(

widget.picList.length,

                        (i) =>GestureDetector(

child:CircleAvatar(

foregroundColor: Theme.of(context).primaryColor,

                        radius:4.0,

                        backgroundColor:index == i

? Theme.of(context).primaryColor

                            : Colors.white,

                      ),

                      onTap: () {

setState(() {

startX =endX =0;

                          index = i;

                        });

                      },

                    ),

                  ).toList(),

                ),

              ),

            )

],

        ),

        alignment: Alignment.center,

      ),

    );

  }

void _getIndex(int delta) {

if (delta >50) {

setState(() {

index--;

        index =index.clamp(0, widget.picList.length -1);

      });

    }else if (delta <50) {

setState(() {

index++;

        index =index.clamp(0, widget.picList.length -1);

      });

    }

}

}

好了。先这样吧,周末再写点数据库(sqllite)和编写界面的心得。

你可能感兴趣的:(Flutter仿微信朋友圈动态)