0

Is it possible to use PageView to reach the following work?

I'd like to use two containers as the main content for a page in PageView.

I've tried to adjust viewPortFraction but it doesn't work as I expected.

The following effect is used by Apple App store and Prime Video and many apps.

Thanks.

enter image description here

enter image description here

Allen
  • 17
  • 1
  • 8

3 Answers3

2

You could try to use an horizontal ListView with PageScrollPhysics() In the physics param.

jamesblasco
  • 1,744
  • 1
  • 9
  • 25
  • That works for me! But, I'm still figuring out how to make two items appear in each screen perfectly. – Allen Jan 08 '20 at 02:52
  • You have two options here for calculate the width of each item: Half Screen->MediaQuery.of(context).size.width/2. Half Size container-> User LayoutBuilder and get the parent size in constraints – jamesblasco Jan 08 '20 at 07:38
  • We can't do onPageChanged with this though. – Oliver Dixon Aug 16 '21 at 17:07
2

You can using viewportFraction params in PageController;

linkaipeng
  • 483
  • 7
  • 9
0

Instead of using PageView, you could just use a ListView with

scrollDirection: Axis.horizontal

This way you could achieve the same result. You would need to somehow provide an explicit height to your ListView if I am not mistaken.

Below is a working sample.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Example'),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Text(
              "Top Games",
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
            ),
          ),
          Container(
            height: 200,
            child: ListView(
              scrollDirection: Axis.horizontal,
              children: <Widget>[
                GameCard(
                  "The Game 1",
                  "A puzzle game",
                  "https://lorempixel.com/200/200/abstract/",
                ),
                GameCard(
                  "The Game 2",
                  "An even beter game",
                  "https://lorempixel.com/200/200/sports/2/",
                ),
                GameCard(
                  "SportMania",
                  "Editors Choice",
                  "https://lorempixel.com/200/200/sports/3/",
                ),
                GameCard(
                  "MonkeySports",
                  "Monkeys playing Sport",
                  "https://lorempixel.com/200/200/abstract",
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}

class GameCard extends StatelessWidget {
  final String gameTitle;
  final String gameDescr;
  final String imgUrl;
  GameCard(
    this.gameTitle,
    this.gameDescr,
    this.imgUrl,
  );

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 3,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
      margin: EdgeInsets.all(5),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          ClipRRect(
            borderRadius: BorderRadius.circular(10),
            child: Image.network(
              imgUrl,
              width: 180,
              height: 130,
              fit: BoxFit.cover,
              alignment: Alignment.center,
            ),
          ),
          Container(
            padding: EdgeInsets.all(4),
            width: 180,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text(
                  gameTitle,
                  maxLines: 2,
                  style: TextStyle(fontWeight: FontWeight.bold),
                ),
                Text(
                  gameDescr,
                  maxLines: 2,
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Example

Hope this gets you started.

  • Xander, Thanks for the demo. I want these two items showing on one screen and want them to be able to stick with edge of screen. `PageScrollPhysics()` and `physics` are the key I was looking for. – Allen Jan 08 '20 at 02:55