在具有不同对齐方式的列中定位小部件

Position widgets in Column with different alignments

我有以下小部件树:

ListViewscrollDirection: Axis.horizontal2child仁。 ColumncrossAxisAlignment: CrossAxisAlignment.center3children。 2nd child 明显比 1st3rd 宽,因此它决定了列的宽度。如何使列中的 1st 小部件左对齐?目前,所有三个小部件都根据 ColumncrossAxisAlignment 水平居中。

这是专栏的布局:

正如预期的那样,Column 的所有三个 children 都位于它的中心。我需要让第一个左对齐。

我的代码:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: 2,
              itemBuilder: (BuildContext context, int index) {
                return Padding(
                  padding: const EdgeInsets.only(
                    left: 10,
                    right: 10,
                  ),
                  child: _composeCard(),
                );
              }),
        ),
      ),
    );
  }

  Widget _composeCard() {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 10),
      child: Expanded(
          child: Container(
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(5.0),
          boxShadow: [
            _composeShadow(dy: 2, blur: 8),
            _composeShadow(dy: 0, blur: 1),
          ],
        ),
        child: Material(
          clipBehavior: Clip.antiAlias,
          child: InkWell(
            child: Padding(
              padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: const [
                  Text("Header"), // I want to push this widget to the left
                  SizedBox(height: 20),
                  Text("Body: Lorem ipsum dolor sit amet"),
                  SizedBox(height: 20),
                  Text("Footer"),
                ],
              ),
            ),
          ),
        ),
      )),
    );
  }

  BoxShadow _composeShadow({
    required double dy,
    required double blur,
    double spread = 0,
  }) {
    return BoxShadow(
      color: const Color(0xFFDBDBDB),
      offset: Offset(0, dy),
      spreadRadius: spread,
      blurRadius: blur,
    );
  }
}

谢谢!

我修改了你的代码以使其工作。 您必须为列表中扩展的项目设置宽度,然后才能使用一行。

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: 2,
              itemExtent: 300,
              itemBuilder: (BuildContext context, int index) {
                return Padding(
                  padding: const EdgeInsets.only(
                    left: 10,
                    right: 10,
                  ),
                  child: _composeCard(),
                );
              }),
        ),
      ),
    );
  }

  Widget _composeCard() {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 10),
      child: Column(
        children: [
          Expanded(
              child: Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(5.0),
              boxShadow: [
                _composeShadow(dy: 2, blur: 8),
                _composeShadow(dy: 0, blur: 1),
              ],
            ),
            child: Material(
              clipBehavior: Clip.antiAlias,
              child: InkWell(
                child: Padding(
                  padding:
                      const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Row(
                        mainAxisSize: MainAxisSize.max,
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: const [
                          Expanded(
                            child: Text("Header"),
                          ),
                        ],
                      ),
                      const SizedBox(height: 20),
                      const Text("Body: Lorem ipsum dolor sit amet"),
                      const SizedBox(height: 20),
                      const Text("Footer"),
                    ],
                  ),
                ),
              ),
            ),
          )),
        ],
      ),
    );
  }

  BoxShadow _composeShadow({
    required double dy,
    required double blur,
    double spread = 0,
  }) {
    return BoxShadow(
      color: const Color(0xFFDBDBDB),
      offset: Offset(0, dy),
      spreadRadius: spread,
      blurRadius: blur,
    );
  }
}

编辑: 如果您不能使用固定的 itemExtend,我有一个替代解决方案,您可以使用 Stack 而不是 Column:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(kPaddingPage),
          child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: 2,
              itemBuilder: (BuildContext context, int index) {
                return Padding(
                  padding: const EdgeInsets.only(
                    left: kPaddingItemH,
                    right: kPaddingItemH,
                  ),
                  child: _composeCard(MediaQuery.of(context).size.width),
                );
              }),
        ),
      ),
    );
  }

  Widget _composeCard(double maxWidth) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 10),
      child: Column(
        children: [
          Expanded(
              child: Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(5.0),
              boxShadow: [
                _composeShadow(dy: 2, blur: 8),
                _composeShadow(dy: 0, blur: 1),
              ],
            ),
            child: Material(
              clipBehavior: Clip.antiAlias,
              child: InkWell(
                child: Container(
                  padding:
                      const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
                  child: Stack(
                    children: [
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: const [
                          Text("Header"),
                          //other elements
                        ],
                      ),
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: const [
                          Text(""),
                          SizedBox(height: 20),
                          Text("Body: Lorem ipsum dolor sit amet"),
                          SizedBox(height: 20),
                          Text("Footer"),
                        ],
                      ),
                    ],
                  ),
                ),
              ),
            ),
          )),
        ],
      ),
    );
  }

  BoxShadow _composeShadow({
    required double dy,
    required double blur,
    double spread = 0,
  }) {
    return BoxShadow(
      color: const Color(0xFFDBDBDB),
      offset: Offset(0, dy),
      spreadRadius: spread,
      blurRadius: blur,
    );
  }
}