Focus on the interface

Everything is Widget in Flutter. No matter how big the interface is, it can be divided into smaller components and put together into one big component.

Depending on the data rendering, each small component can be responsible for different business logic.

components

coding

ATHFollowContent

import 'follow_item.dart';

class ATHFollowContent extends StatefulWidget {
  @override
  _ATHFollowContentState createState() => _ATHFollowContentState();
}

class _ATHFollowContentState extends State<ATHFollowContent>
    with AutomaticKeepAliveClientMixin {
  / / the total number of

  @override
  Widget build(BuildContext context) {
    super.build(context);
    List<ATHFollowItemModel> followItemList = MockFollowItemData.followItemList;
    return SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) {
          ATHFollowItemModel followItem = followItemList[index];
          return ATHFollowItem(
            followItem: followItem,
          );
        },
        childCount: followItemList.length,
      ),
    ),);
  }

  @override
  bool get wantKeepAlive => true;
}

Copy the code
  • Keep the state AutomaticKeepAliveClientMixin interface, using the current component
  • Implementation bool get wantKeepAlive => true; function
  • Create and build each Item by ATHFollowItem

ATHFollowItem

class ATHFollowItem extends StatelessWidget {
  final ATHFollowItemModel followItem;

  const ATHFollowItem({Key key, this.followItem}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          ATHFollowUserInfo(followItem: followItem),
          ATHFollowContent(followItem: followItem),
          followItem.images.length > 0? ATHFollowGridImage(followItem: followItem) : SizedBox(), ATHFollowComment(followItem: followItem), ATHFollowOperation(followItem: followItem), Padding( padding: EdgeInsets.symmetric(vertical: kSize20), child: ATHItemDivider(), ), ], ), ); }}Copy the code

ATHFollowUserInfo

  • The user profile picture and introduction information are displayed
class ATHFollowUserInfo extends StatelessWidget {
  final ATHFollowItemModel followItem;

  const ATHFollowUserInfo({Key key, this.followItem}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        Container(
          child: ATHUserAvatar(
            avatarPath: followItem.poetryItem.poetryAvatar,
          ),
        ),
        Expanded(
          child: Container(
            padding: EdgeInsets.only(left: kSize24),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Row(
                  children: <Widget>[
                    Text(
                      followItem.poetryItem.poetryAuthor ?? "",
                      style: TextStyle(color: kColor33, fontSize: kSize30),
                    ),
                  ],
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    Text(
                      followItem.createTime ?? "", style: TextStyle(color: kColor33), ), ], ) ], ), ), ) ], ); }}Copy the code

ATHFollowContent

  • According to the content
class ATHFollowContent extends StatelessWidget {
  final ATHFollowItemModel followItem;

  const ATHFollowContent({Key key, this.followItem}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Padding(
          padding: EdgeInsets.symmetric(vertical: kSize20),
          child: Text(
            followItem.poetryItem.poetryTitle ?? "",
            style: TextStyle(fontSize: kSize32),
          ),
        ),
        Text(followItem.poetryItem.poetryContent ?? "", style: TextStyle(color: kColor66, fontSize: kSize32)) ], ); }}Copy the code

ATHFollowGridImage

  • Display images, multiple images, as a GridView

class ATHFollowGridImage extends StatelessWidget {
  final ATHFollowItemModel followItem;

  const ATHFollowGridImage({Key key, this.followItem}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    List<String> imageList = followItem.images;
    return GridView.custom(
      shrinkWrap: true,
      padding: EdgeInsets.only(top: kSize20),
      physics: NeverScrollableScrollPhysics(),
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 3,
        mainAxisSpacing: kSize20,
        crossAxisSpacing: kSize20,
      ),
      childrenDelegate: SliverChildBuilderDelegate((context, position) {
        String imagePath = imageList[position];
        returnContainer( child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(kSize8)), child: Image.asset( imagePath, fit: BoxFit.cover, ), ), ); }, childCount: imageList.length), ); }}Copy the code

ATHFollowComment

  • Comment on the component
class ATHFollowComment extends StatelessWidget {
  final ATHFollowItemModel followItem;

  const ATHFollowComment({Key key, this.followItem}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      margin: EdgeInsets.only(top: kSize20),
      padding: EdgeInsets.all(kSize16),
      decoration: BoxDecoration(
          color: kColorF1F1F1,
          borderRadius: BorderRadius.all(Radius.circular(kSize8))),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  SvgPicture.asset('assets/icons/icon_hot.svg', width: kSize30),
                  Text(
                    101> =100 ? "Buzz" : "",
                    style: TextStyle(color: kColor33, fontSize: kSize22),
                  )
                ],
              ),
              Text(
                "${followItem.commentItem.commentLike}Praise. "",
                style: TextStyle(color: kColor33),
              )
            ],
          ),
          Padding(
            padding: EdgeInsets.only(top: kSize8),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Text(
                      followItem.commentItem.commentAuthor + ":" ?? "",
                      style: TextStyle(color: kPrimaryColor),
                    ),
                    Text(
                      followItem.commentItem.commentContent ?? "",
                      style: TextStyle(color: kColor33),
                    ),
                  ],
                ),
                Text(
                  followItem.commentItem.commentTime ?? "", style: TextStyle(color: kColor33, fontSize: kSize24), ), ], ), ) ], ), ); }}Copy the code

ATHFollowOperation

  • Can operate buttons, X display share, comment, like…
class ATHFollowOperation extends StatelessWidget {
  final ATHFollowItemModel followItem;

  const ATHFollowOperation({Key key, this.followItem}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(top: kSize20),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
              padding:
                  EdgeInsets.symmetric(horizontal: kSize10, vertical: kSize4),
              decoration: BoxDecoration(
                  borderRadius: BorderRadius.all(Radius.circular(kSize8)),
                  shape: BoxShape.rectangle,
                  color: kColorF1F1F1),
              child: Text(
                followItem.tag ?? "",
                maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: kSize24, color: kColor99), )), Padding( padding: EdgeInsets.only(top: kSize16), child: ATHOperatorView(), ), ], ), ); }}Copy the code

Build simulated data

  • Driven by data, the interface displays according to data
class MockFollowItemData {
  static List<ATHFollowItemModel> followItemList = [
    ATHFollowItemModel(
      poetryItem: ATHPoetryItemModel(
        poetryAuthor: "Du Fu - A Wild old man in Shaoling",
        poetryTitle: "High",
        poetryAvatar: "assets/images/dufu.jpg",
        poetryContent:
            "The wind is so strong that the high ape cries out, and the white bird flies back to nagisa. \n Endless falling wood rustling, not the Yangtze River rolling. \n Wanli sad autumn often guest, more than a hundred years of illness alone stage. \n Hardship bitter hate numerous frost temples, down and out new stop liquor cup.",
      ),
      images: [
        'assets/images/qrcode_430.jpg'.'assets/images/qrcode_430.jpg'.'assets/images/qrcode_430.jpg',
      ],
      commentItem: ATHCommentItemModel(
          commentAuthor: "Jiang",
          commentAuthorAvatar: "assets/images/libai.jpg",
          commentContent: "Ha ha ha, yes yes.",
          commentLike: 831,
          commentTime: "The 752-02-23 23:23:23"),
      createTime: "The 752-02-22 22:22:22",
      tag: "Bleak and desolate.",
      likeCount: 678,
    ),
    ATHFollowItemModel(
      poetryItem: ATHPoetryItemModel(
        poetryAuthor: "Li Bai - Shixian",
        poetryTitle: "Three five seven Words/Autumn Wind Words",
        poetryAvatar: "assets/images/libai.jpg",
        poetryContent:
            "Autumn wind is clear, autumn moon is bright, \n fallen leaves gather also scattered, jackdaw habitat is back startled. \n Acacia meet know when? Now this night shame! \n into my acacia door, know my acacia bitter, \n everlasting acacia xi looks recall, short Acacia Xi infinite, \n early know so stumble, such as the original mo met.",
      ),
      images: [
        'assets/images/qrcode_430.jpg',
      ],
      commentItem: ATHCommentItemModel(
          commentAuthor: "Du Fu - A Wild old man in Shaoling",
          commentAuthorAvatar: "assets/images/libai.jpg",
          commentContent: "Emm, interesting.",
          commentLike: 9831,
          commentTime: "The 752-10-23 02:00:13"),
      createTime: "The 752-10-23 01:00:13",
      tag: "The moon hangs high in the sky",
      likeCount: 1678,)]; }Copy the code

Add home to tabContents

TabBarView _buildTabBarView() {
    List<Widget> tabContents = [];
    for (int index = 0; index < _tabsText.length; index++) {
      if (index == 0) {
        // Add this
        tabContents.add(ATHFollowContent());
      } else if (index == 1) {
        tabContents.add(ATHRecommendContent());
      } else{ tabContents.add(Center(child: Text(_tabsText[index]))); }}return TabBarView(controller: _tabController, children: tabContents);
  }
Copy the code
  • This step can be compiled to see the effect

Serialize previous articles

Learn from Flutter 2.0 – Project Construction