點燈坊

失くすものさえない今が強くなるチャンスよ

GestureDetector 取代 ListTile 的 ListView

Sam Xiao's Avatar 2024-11-30

ListView 一般都會搭配 ListTile,但 ListTile 自帶 Padding,且無法清除,最有效的方式是使用沒有自帶 Padding 的 GestureDetector 取代 ListTile

Version

Flutter 3.24

Flutter

gesture01

  • Android 與 iOS 都成功使用 GestureDetector 實現 ListView

GestureDetector

import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  const Home({super.key});

  
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final List<String> _data = List.generate(
    3,
    (index) => 'Item ${index + 1}',
  );

  
  Widget build(BuildContext context) {
    var appBar = AppBar(
      title: const Text(
        'ListView GestureDetector',
      ),
    );

    var listView = ListView.builder(
      itemCount: _data.length,
      padding: EdgeInsets.zero,
      itemBuilder: (context, index) {
        return GestureDetector(
          onTap: () {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text(
                  _data[index],
                ),
              ),
            );
          },
          child: Container(
            color: Colors.transparent,
            padding: EdgeInsets.zero,
            child: Text(
              _data[index],
            ),
          ),
        );
      },
    );

    return Scaffold(
      appBar: appBar,
      body: listView,
    );
  }
}

Line 23

var listView = ListView.builder(
  itemCount: _data.length,
  padding: EdgeInsets.zero,
  itemBuilder: (context, index) {
    return GestureDetector(
      onTap: () {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(
               _data[index],
            ),
          ),
        );
      },
      child: Container(
        color: Colors.transparent,
        padding: EdgeInsets.zero,
        child: Text(
          _data[index],
        ),
      ),
    );
  },
);
  • ListView:外層一樣使用 ListView
    • padding:可在 ListView 直接設定 padding
    • GestureDetector:使用 GestureDetector 取代 ListTile
      • ContainerGestureDetector 並沒有提供 padding,須由 Container 設定
        • color:設定項目的背景色
        • padding:設定項目的 padding
          • Text:設定項目顯示文字

Conclusion

  • 使用 GestureDetector 的優點是 padding 可完全自主,不再受 ListTile 預設 padding 所限制,可更精確地呈現 prototype 的 layout