Flutter实现多类型列表

2,413 阅读2分钟

1、实现效果

本次主要的实现效果为类似百度贴吧的帖子详情页面。 image

可以从图中看出,这个页面是一个列表,有五种类型,分别是

  • 动态详情
  • 分割线
  • 评论Title
  • 评论空态
  • 评论详情

2、实现原理

实现的原理其实和Android原生ListView或者RecyclerView一样, 就是根据不同的数据类型创建不同的子Item

//Listview在创建的时候, 根据不同的数据类型,返回不同的Widget
  Widget _buildListViewCell(Object object) {
    if (object is MomentDetail) {
      return MomentDetailWidget(object);
    } else if (object is DividerState) {
      return DividerWidget();
    } else if (object is num) {
      return CommentTitleWidget(object);
    } else if (object is CommentEmptyState) {
      return CommentEmptyWidget();
    } else if (object is CommentDetail) {
      return CommentDetailWidget(object);
    } else {
      return Container();
    }
  }

3、实现细节

1、创建各个类型的数据以及ViewHolder

1、动态详情
class MomentDetail {
  final String userName;
  final String detailContent;

  MomentDetail(this.userName, this.detailContent);
}


import 'package:flutter/cupertino.dart';
import 'package:flutterapp/bean/moment_detail.dart';

class MomentDetailWidget extends StatelessWidget {
  final MomentDetail momentDetail;

  MomentDetailWidget(this.momentDetail);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.only(left: 16, top: 8, bottom: 8, right: 16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(
            "${momentDetail.userName}  发表了",
            style: TextStyle(fontSize: 16),
          ),
          Text(
            momentDetail.detailContent,
            style: TextStyle(fontSize: 20),
          ),
        ],
      ),
    );
  }
}

2、分割线
class DividerState{

}

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

class DividerWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Divider(
      height: 8,
      thickness: 8,
      color: Colors.black12,
    );
  }
}

3、评论Title
//评论title的数据类型用数字

import 'package:flutter/cupertino.dart';

class CommentTitleWidget extends StatelessWidget {
  final int commentNum;

  CommentTitleWidget(this.commentNum);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.only(
        left: 16,
        top: 16,
      ),
      child: Text("评论  $commentNum"),
    );
  }
}
4、评论空态
class CommentEmptyState {

}

import 'package:flutter/cupertino.dart';

class CommentEmptyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.only(top: 40, bottom: 40),
      child: Center(
        child: Text("评论内容为空,赶紧发表条评论吧"),
      ),
    );
  }
}

5、评论详情
class CommentDetail {
  final String userName;
  final String commentContent;

  CommentDetail(this.userName, this.commentContent);
}


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutterapp/bean/comment_detail_state.dart';

class CommentDetailWidget extends StatelessWidget {
  final CommentDetail commentDetail;

  CommentDetailWidget(this.commentDetail);

  @override
  Widget build(BuildContext context) {
    return Container(
        margin: EdgeInsets.only(left: 16, top: 8, bottom: 8, right: 16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(
              "${commentDetail.userName}",
              style: TextStyle(fontSize: 16, color: Colors.blue),
            ),
            Text(
              commentDetail.commentContent,
              style: TextStyle(fontSize: 20),
            ),
          ],
        ));
  }
}

2、创建ListView

import 'package:flutter/material.dart';
import 'package:flutterapp/bean/comment_detail_state.dart';
import 'package:flutterapp/bean/comment_empty_state.dart';
import 'package:flutterapp/bean/divider_state.dart';
import 'package:flutterapp/bean/moment_detail.dart';
import 'package:flutterapp/cell/comment_detail_widget.dart';
import 'package:flutterapp/cell/comment_empty_widget.dart';
import 'package:flutterapp/cell/comment_title_widget.dart';
import 'package:flutterapp/cell/divider_widget.dart';
import 'package:flutterapp/cell/moment_detail_widgert.dart';

void main() => runApp(ListWidget());

class ListWidget extends StatelessWidget {
  List list;

  ListWidget() {
    list = List();
    list.add(MomentDetail("蓝莲花", "没有什么能够阻挡,你对自由的向往"));
    list.add(DividerState());
    list.add(50);
    list.add(CommentEmptyState());
    list.add(CommentDetail("路人甲", "你说得对"));
    list.add(CommentDetail("路人乙", "我很赞成"));
    list.add(CommentDetail("路人丙", "老铁666"));
    list.add(CommentDetail("路人丁", "哈哈哈哈哈"));
    list.add(CommentDetail("路人甲", "你说得对"));
    list.add(CommentDetail("路人乙", "我很赞成"));
    list.add(CommentDetail("路人丙", "老铁666"));
    list.add(CommentDetail("路人丁", "哈哈哈哈哈"));
  }

  Widget _buildListViewCell(Object object) { // 重点是这个方法,ListView才创建Item的时,根据不同的数据类型返回不同的widget,以实现多类型列表
    if (object is MomentDetail) {
      return MomentDetailWidget(object);
    } else if (object is DividerState) {
      return DividerWidget();
    } else if (object is num) {
      return CommentTitleWidget(object);
    } else if (object is CommentEmptyState) {
      return CommentEmptyWidget();
    } else if (object is CommentDetail) {
      return CommentDetailWidget(object);
    } else {
      return Container();
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Test',
      home: Scaffold(
        appBar: AppBar(title: new Text('动态详情')),
        body: ListView.builder(
          itemCount: list.length,
          itemBuilder: (context, index) {
            return _buildListViewCell(list[index]); //根据数据去构造不同的widget填充到ListView中
          },
        ),
      ),
    );
  }
}