【问题标题】:Different size images in horizontal List view / Grid view with fix height and dynamic width in flutter水平列表视图/网格视图中不同尺寸的图像,在颤动中具有固定高度和动态宽度
【发布时间】:2021-06-06 07:18:39
【问题描述】:

我想创建一个水平的 ListViewGridView,图像的高度是固定的,但 图像的宽度应该是动态的

以下是我正在尝试执行但无法获得预期输出的代码。我还添加了说明预期输出的设计截图

带列表视图

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


class ViewPager extends StatefulWidget {
  createState() => _ViewPager();
}

class _ViewPager extends State<ViewPager> {

  static final exercise_image1 = "https://drive.google.com/uc?export=download&id=1eDhXVJrNExRwi85pQGCOAwPYi7X-sA0l";
  static final exercise_image2 = "https://drive.google.com/uc?export=download&id=1ifjpLw2ocBAIbEOIhsTtczf8dWuvexri";


  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        children: [
          _imagesList(images: [exercise_image1, exercise_image2]),
        ],
      ),
    );
  }



  Widget _imagesList({List<String> images}) {

    return Container(
      width: double.maxFinite,
      height: 150,
      color: Colors.red,
      child: ListView(
        scrollDirection: Axis.horizontal,
        children: [
          _imageListItem(imagePath: images.first),
          _imageListItem(imagePath: images.last),
        ],
      ),
    );

  }

  Widget _imageListItem({@required String imagePath}) {

    return CachedNetworkImage(
      width: 200, // I want this to be according to the image width
      imageUrl: imagePath,
      placeholder: (context, url) => Container(
        child: CircularProgressIndicator(),
      ),
      imageBuilder: (context, imageProvider) => Container(
        decoration: BoxDecoration(
          image: DecorationImage(
              image: imageProvider,
              fit: BoxFit.fitHeight
          ),
        ),
      ),
    );

  }

}

带有网格视图

与网格视图相同的问题,我们设置了网格视图的高度,但无法为图像提供动态宽度

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


class ViewPager extends StatefulWidget {
  createState() => _ViewPager();
}

class _ViewPager extends State<ViewPager> {

  static final exercise_image1 = "https://drive.google.com/uc?export=download&id=1eDhXVJrNExRwi85pQGCOAwPYi7X-sA0l";
  static final exercise_image2 = "https://drive.google.com/uc?export=download&id=1ifjpLw2ocBAIbEOIhsTtczf8dWuvexri";


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          height: 200,
          child: _imagesList(images: [exercise_image1, exercise_image2]),
        ),
      ),
    );


  }


  Widget _imagesList({List<String> images}) {

    return GridView.count(
      crossAxisCount: 1,
      scrollDirection: Axis.horizontal,
      children: [
        _imageListItem(imagePath: images[0]),
        _imageListItem(imagePath: images[1]),
      ],
    );

  }

  Widget _imageListItem({@required String imagePath}) {

    return CachedNetworkImage(
      imageUrl: imagePath,
      placeholder: (context, url) => Container(
        child: CircularProgressIndicator(),
      ),
      imageBuilder: (context, imageProvider) => Container(
        decoration: BoxDecoration(
          image: DecorationImage(
              image: imageProvider,
              fit: BoxFit.fitHeight
          ),
        ),
      ),
    );

  }

}

【问题讨论】:

  • 我想你正在寻找flutter_staggered_grid_view。
  • 我也试过了,但这也不是动态的(意味着不按图像宽度工作)。
  • 您的情况是否需要 imageBuilder 部分?您是否尝试在构建器下方添加更多小部件?似乎是破坏布局的部分,因为Container 无法从自己的装饰中获得正确的图像大小

标签: flutter dart flutter-layout


【解决方案1】:

实现这一点的一种方法是这样的。

class _MyWidgetState extends State<MyWidget> {
  static final exercise_image1 = "https://drive.google.com/uc?export=download&id=1eDhXVJrNExRwi85pQGCOAwPYi7X-sA0l";
  static final exercise_image2 = "https://drive.google.com/uc?export=download&id=1ifjpLw2ocBAIbEOIhsTtczf8dWuvexri";

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          height: 200,
          child: _imagesList(images: [exercise_image1, exercise_image2]),
        ),
      ),
    );
  }

  Widget _imagesList({List<String> images}) {
    return ListView(
      scrollDirection: Axis.horizontal,
      children: [
        _imageListItem(imagePath: images[0]),
        _imageListItem(imagePath: images[1]),
      ],
    );
  }

  Widget _imageListItem({@required String imagePath}) {
    return CachedNetworkImage(
      imageUrl: imagePath,
      placeholder: (context, url) => Container(
        child: CircularProgressIndicator(),
      ),
    );
  }
}

【讨论】:

    【解决方案2】:

    尝试像这样使用列表视图。它给出了你想要的输出。

         @override
      Widget build(BuildContext context) {
        Widget _imageListItem({@required String imagePath}) {
          return   CachedNetworkImage(
            imageUrl: imagePath,
            placeholder: (context, url) => CircularProgressIndicator(),
            errorWidget: (context, url, error) => Icon(Icons.error),
          );
        }
        Widget horizontalList1 = new Container(
          margin: EdgeInsets.symmetric(vertical: 20.0),
          height: 200.0,
          child:
          ListView(
            scrollDirection: Axis.horizontal,
            children: <Widget>[
              _imageListItem(imagePath: exercise_image1),
              SizedBox(width: 2,),
              _imageListItem(imagePath: exercise_image2),
    
            ],
          ),
        );
        return new Scaffold(
          body: new Center(
            child: new Container(
              child: ListView(
                scrollDirection: Axis.vertical,
                children: <Widget>[
                  horizontalList1,
                ],
              ),
            ),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }}
    

    【讨论】:

    • @user3686123 您尝试过还是需要更多帮助?
    【解决方案3】:

    您所说的是纵横比,您希望它适合宽度。

    在图片小部件中,将fit设置为BoxFit.fitWidth,问题就解决了。

    阅读更多相关信息here

    【讨论】:

    • 不,这不是纵横比。我说的是任何宽度的固定高度。 In ratio 小部件将以相同的比例在宽度和高度上扩展。但就我而言,我只想给出固定高度,但宽度可以是任意的
    • BoxFit.fitHeight -> (请检查代码,它已经是 der,我也用很多其他方式厌倦了这个)
    • 对不起我的错字,它必须是 fitWidth 而不是 Height
    • 它的运行代码,如果你能试运行一下就好了
    • 我不明白你的意思。你想说什么?
    【解决方案4】:

    试试这个代码:

    import 'package:cached_network_image/cached_network_image.dart';
    import 'package:flutter/material.dart';
    
    class ViewPager extends StatelessWidget {
      const ViewPager({Key key}) : super(key: key);
    
      static final exerciseImages = [
        "https://drive.google.com/uc?export=download&id=1eDhXVJrNExRwi85pQGCOAwPYi7X-sA0l",
        "https://drive.google.com/uc?export=download&id=1eDhXVJrNExRwi85pQGCOAwPYi7X-sA0l",
        "https://drive.google.com/uc?export=download&id=1eDhXVJrNExRwi85pQGCOAwPYi7X-sA0l",
        "https://drive.google.com/uc?export=download&id=1ifjpLw2ocBAIbEOIhsTtczf8dWuvexri",
        "https://drive.google.com/uc?export=download&id=1ifjpLw2ocBAIbEOIhsTtczf8dWuvexri",
        "https://drive.google.com/uc?export=download&id=1ifjpLw2ocBAIbEOIhsTtczf8dWuvexri",
        "https://drive.google.com/uc?export=download&id=1ifjpLw2ocBAIbEOIhsTtczf8dWuvexri",
        // add more image url here. anything you want.
      ];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Container(
              height: 150,
              padding: EdgeInsets.all(12),
              // shuffled to make it a lot more dynamic. demonstration only
              child: _imagesList(images: exerciseImages..shuffle()),
            ),
          ),
        );
      }
    
      Widget _imagesList({List<String> images}) {
        return ListView.builder(
          physics: BouncingScrollPhysics(), // just for coolness.
          itemCount: images.length,
          scrollDirection: Axis.horizontal,
          itemBuilder: (context, index) {
            return _imageListItem(imagePath: images[index]); // access each images by their index.
          },
        );
      }
    
      Widget _imageListItem({@required String imagePath}) {
        return Padding(
          padding: const EdgeInsets.all(4), // add padding so the edges of the image is clearly distinguishable.
          child: CachedNetworkImage(
            imageUrl: imagePath,
            placeholder: (context, url) {
              return Center(
                child: Container(
                  height: 32, // properly size the loading indicators.
                  width: 32, // properly size the loading indicators.
                  child: CircularProgressIndicator(),
                ),
              );
            },
          ),
        );
      }
    }
    

    我还稍微改进了代码的结构。让它更有活力。解决方法是您根本不将大小放在 CachedNetworkImage 小部件中。只需给它一个网址和占位符。带有height: 150 的父容器的代码很好。缓存网络图像会自动适应该高度。

    【讨论】:

      猜你喜欢
      • 2021-02-11
      • 2021-10-25
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多