ListTile 的 SelectedTileColor 不起作用

Sam*_*bhi 9 flutter

我有一个ListView包含ListTile在选择时改变颜色的 s 。但是,在下面的代码中,当和 之间存在中间Container或时,不起作用。我关注了这个问题并用它包裹了我的但仍然不起作用。SizedBoxListViewScaffoldSelectedTileColorListViewInk

在下面的代码中,如果您通过将第 20 行BottomPanel替换为 来删除中间小部件,那么它将起作用。出了什么问题?为什么会阻止发生?BottomPanelVehicleTypePanelBottomPanelSelectedTileColor

https://dartpad.dev/?id=ddb60a7657ddb0cc30b4bdd0d86754cd


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

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: BottomPanel(),
        ),
      ),
    );
  }
}

class BottomPanel extends StatelessWidget {
  BottomPanel({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final mediaQuery = MediaQuery.of(context);

    return SizedBox(
      child: DecoratedBox(
        decoration: BoxDecoration(
            color: Theme.of(context).scaffoldBackgroundColor,
            boxShadow: [
              BoxShadow(
                  color: Colors.black.withOpacity(0.1),
                  blurRadius: 10,
                  spreadRadius: 5)
            ]),
        child: AnimatedSwitcher(
            duration: const Duration(milliseconds: 300),
            child: VehicleTypePanel(),
            layoutBuilder: (currentChild, previousChildren) => Stack(
                  children: [
                    ...previousChildren,
                    if (currentChild != null) currentChild,
                  ],
                )),
      ),
      height: mediaQuery.size.height,
      width: mediaQuery.size.width,
    );
  }
}

List<Map<String, String>> vehicles = [
  {"type": "car", 'seats': '4', 'image': 'assets/car.jpeg'},
];

class VehicleTypePanel extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        const VehicleItem(
            type: "car",
            seats: "4",
            image: 'assets/car.jpeg',
            index: 0,
            selectedIndex: 0),
        const Divider(),
        const VehicleItem(
            type: "van",
            seats: "6",
            image: 'assets/van.jpeg',
            index: 1,
            selectedIndex: 0),
        const Divider(),
        //drop down textbutton with icon
        FractionallySizedBox(widthFactor: .8, child: PaymentMethod()),
        const SizedBox(height: 10),
        FractionallySizedBox(
          widthFactor: .8, // means 100%, you can change this to 0.8 (80%)
          child: ElevatedButton(
            style: ElevatedButton.styleFrom(
              fixedSize: const Size.fromHeight(50),
              elevation: 4,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(50)),
            ),
            onPressed: () {},
            child: const Text('Select Vehicle'),
          ),
        ),
      ],
    );
  }
}

class PaymentMethod extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        const Icon(Icons.person),
        const SizedBox(width: 10),
        Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            RichText(
              text: const TextSpan(
                children: [
                  TextSpan(
                    style: TextStyle(color: Colors.black),
                    text: "Payment Method",
                  ),
                  WidgetSpan(
                    alignment: PlaceholderAlignment.middle,
                    child: Icon(Icons.arrow_drop_down, size: 18),
                  ),
                ],
              ),
            ),
            const Text("Cash"),
          ],
        ),
      ],
    );
  }
}

class VehicleItem extends StatelessWidget {
  final String type;
  final String seats;
  final String image;
  final int index;
  final int selectedIndex;
  //final Function(GooglePlace, bool) onPlaceSelected;
  const VehicleItem(
      {Key? key,
      required this.type,
      required this.seats,
      required this.image,
      required this.index,
      required this.selectedIndex})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListTile(
      onTap: () {},
      selected: index == selectedIndex,
      selectedTileColor: Colors.amber,
      selectedColor: Colors.deepOrange,
      title: Text(type),
      subtitle: RichText(
        text: TextSpan(
          style: const TextStyle(color: Colors.deepOrange),
          children: [
            const WidgetSpan(
              alignment: PlaceholderAlignment.middle,
              child: Icon(Icons.person, size: 18),
            ),
            TextSpan(
              text: "$seats seats",
            ),
          ],
        ),
      ),
      trailing: const Text("10\$"),
    );
  }
}


Run Code Online (Sandbox Code Playgroud)

jei*_*iea 17

ListTile 文档中,

tileColor、selectedTileColor、focusColor 和hoverColor 不是由列表图块本身绘制的,而是由材质小部件祖先绘制的。这一般没有什么影响。但是,如果不透明小部件(如 Container(color: Colors.white))包含在 ListTile 及其 Material 祖先之间,则不透明小部件将遮盖材质小部件及其背景tileColor 等。如果这是一个问题,则一可以将材质小部件包裹在列表图块周围

所以只需替换VehicleTypePanel()Material(type: MaterialType.transparency, child: VehicleTypePanel()).