Zeffry Reynando
Zeffry Reynando

Reputation: 3899

Flutter : Different width container depend of value

different width container

I want to implement a design like the one above, the problem is i don't know how to make the container size different depending on the number.

Expectaion

enter image description here

Source code

final userPlaylist = {
  'Kaguya Love Dramatic': 10,
  'Saenai Heroine': 8,
  'Jujutsu Kaisen Kaikai Kitan': 3,
  'Jujutsu Kaisen LOST IN PARADISE': 2,
  'Kaguya Sama DADDY DADDY DO': 2,
};

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      ListView.builder(
                        shrinkWrap: true,
                        physics: const NeverScrollableScrollPhysics(),
                        itemCount: userPlaylist.length,
                        itemBuilder: (context, index) {
                          final song = userPlaylist.keys.elementAt(index);
                          final totalPlay = userPlaylist.values.elementAt(index);
                          final margin = margins[index];
                          return Padding(
                            padding: const EdgeInsets.only(top: 12),
                            child: Row(
                              children: [
                                Expanded(child: CircleAvatar()),
                                SizedBox(width: 10),
                                Expanded(
                                  flex: 4,
                                  child: Column(
                                    crossAxisAlignment: CrossAxisAlignment.stretch,
                                    children: [
                                      Text(song),
                                      SizedBox(height: 10),
                                      Container(
                                        margin:EdgeInsets.only(right:margin),
                                        height: 20,
                                        decoration: BoxDecoration(
                                          color: Colors.green,
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                                SizedBox(width: 10),
                                Expanded(child: Text(totalPlay.toString(),style: TextStyle(color:Colors.white),))
                              ],
                            ),
                          );
                        },
                      ),
                    ],
                  );
  }
}

and this size container applies if there are numbers that have the same value

Upvotes: 0

Views: 224

Answers (2)

ttyip
ttyip

Reputation: 1261

Add a variable max right after the margin definition. This reduces the list of values to the largest value in the list:

final max = userPlaylist.values.reduce((curr, next) => curr > next ? curr : next);

Replace the green Container with:

Row(
  children: [
    Expanded(
      flex: totalPlay,
      child: Container(
        height: 20,
        decoration: BoxDecoration(
          color: Colors.green,
        ),
      ),
    ),
    Expanded(
      flex: max - totalPlay,
      child: Container(),
    )
  ],
)

The green bar is a Row widget containing two Expanded widgets. The first Expanded widget has flex: totalPlay, and the second flex: max - totalPlay. This would show a green bar, the length is the song's value proportional to the max value.

(margin is not used)

Upvotes: 1

Alexey Inkin
Alexey Inkin

Reputation: 2039

Make each bar like this:

Row(
  children: [
    Expanded(
      flex: totalPlay,
      child: Container(color: Colors.green),
    ),
    Expanded(
      flex: maxTotalPlay - totalPlay,
      child: Container(),
    ),
  ],
),

flexes of two Expanded widgets should divide the parent width proportionally among them.

Upvotes: 1

Related Questions