首页 > 解决方案 > 如何在flutter中制作排行榜?

问题描述

我是 Flutter 的新手,我想在左侧和用户个人资料上制作一系列数字,如下所示。

这就是我的意思

我最终是这样的

这是我的

这是我的代码

import 'package:DoNation/model/leaderboard_item.dart';
import 'package:DoNation/shared/utils/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class LeaderBoardPage extends StatefulWidget {
  @override
  _LeaderBoardPageState createState() => _LeaderBoardPageState();
}

class _LeaderBoardPageState extends State<LeaderBoardPage> {
  List<LeaderBoardItem> _leaderBoardItems = List<LeaderBoardItem>();

  @override
  Widget build(BuildContext context) {
    generateDummyData();

    return Container(
        child: ListView.builder(
          itemCount: _leaderBoardItems.length,
          itemBuilder: (BuildContext ctxt, int index) => buildList(ctxt, index)
        ),
      );
    // );
  }

  Widget buildList(BuildContext ctxt, int index) {
    int ind = index + 1;

    Widget crown;

    if (ind == 1) {
      crown = Padding(
        padding: const EdgeInsets.only(right: 0.0),
        child: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Center(child: Icon(FontAwesomeIcons.crown, size: 36, color: Colors.yellow,)),
            Padding(
              padding: const EdgeInsets.only(left: 8.0, top: 6),
              child: Center(child: Text('1', style: TextStyle(fontSize: 17, fontWeight: FontWeight.bold),)),
            )
          ],
        )
      );
    } else if (ind == 2) {
      crown = Padding(
        padding: const EdgeInsets.only(right: 0.0),
        child: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Center(child: Icon(FontAwesomeIcons.crown, size: 36, color: Colors.grey[300],)),
            Padding(
              padding: const EdgeInsets.only(left: 8.0, top: 6),
              child: Center(child: Text('2', style: TextStyle(fontSize: 17, fontWeight: FontWeight.bold),)),
            )
          ],
        )
      );
    } else if (ind == 3) {
      crown = Padding(
        padding: const EdgeInsets.only(right: 0.0),
        child: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Center(child: Icon(FontAwesomeIcons.crown, size: 36, color: Colors.orange[300],)),
            Padding(
              padding: const EdgeInsets.only(left: 8.0, top: 6),
              child: Center(child: Text('3', style: TextStyle(fontSize: 17, fontWeight: FontWeight.bold),)),
            )
          ],
        )
      );
    } else {
    crown = CircleAvatar(
          backgroundColor: Colors.grey,
          radius: 13,
          child: Text(
            ind.toString(), 
            style: TextStyle(
              color: Colors.black,
              fontWeight: FontWeight.bold,
              fontSize: 15
              ),)
        );
    }

    return Padding(
      padding: const EdgeInsets.only(left:8.0,right: 8.0,top: 10),
      child: Container(
        height: 100,
        decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.all(Radius.circular(15.0)),
            boxShadow: [BoxShadow(color: Colors.black26,blurRadius: 5.0)]
        ),
        child: Row(
          children: <Widget>[
            Expanded(
              child: Align(
                alignment: Alignment.centerLeft,
                child: Padding(
                  padding: const EdgeInsets.only(right: 0.0),
                  child: Row(
                    children: <Widget>[
                       Align(
                        alignment: Alignment.centerLeft,
                        child: Padding(
                          padding: const EdgeInsets.only(left: 15.0, right: 25),
                          child: crown,
                        ),
                      ),

                      Align(
                        child: CircleAvatar(
                          backgroundColor: Colors.red.shade800,
                          child: Text('GI'),
                          radius: 30,
                        ),
                      ),

                      Align(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Padding(
                              padding: const EdgeInsets.only(left: 8.0, top: 5),
                              child: Text(_leaderBoardItems[index].name, style: TextStyle(color: Colors.black,fontWeight: FontWeight.bold,fontSize: 18),),
                            ),
                          ],
                        )
                      ),
                    ],
                  ),
                ),
              ),
            ),
            Align(
              alignment: Alignment.centerRight,
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text(_leaderBoardItems[index].totalCalory + ' ' + AppLocalizations.of(context).i18nKCal, style: TextStyle(color: Colors.black,fontWeight: FontWeight.bold,fontSize: 18),),
              ),
            )
          ],
        ),
      ),
    );
  }

  void generateDummyData() {
    _leaderBoardItems = List<LeaderBoardItem>();

    for (var i = 1; i < 21; i++) {
      LeaderBoardItem lbi = LeaderBoardItem(
        userId: 'user$i',
        name: 'User $i',
        email: 'user$i@gmail.com',
        totalCalory: (1000 + i).toString(),
      );

      _leaderBoardItems.add(lbi);
    }

    _leaderBoardItems =_leaderBoardItems.reversed.toList();
  }
}

我找不到在我的代码中实现堆栈小部件的方法,以使序列号和用户配置文件图像看起来像我想要的方式,如上所示。有解决办法吗?

这有可能让我的代码看起来更干净吗?谢谢

标签: flutter

解决方案


添加一个 Row 子项(具有数值)并使用 Padding、Container、Width/Height 属性相应地定位它。


推荐阅读