You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中实现DataTable双指缩放功能的解决方案求助

实现Flutter DataTable的双指缩放功能

直接用Flutter官方提供的InteractiveViewer组件就能轻松实现双指缩放,它原生支持捏合缩放、平移手势,不需要自己处理复杂的手势逻辑。

修改方案

把需要缩放的DataTable(或整个目标区域)包裹在InteractiveViewer中,通过参数可灵活控制缩放范围、边界等行为。

修改后的完整代码片段

ListView(children: <Widget>[
  SizedBox(
    width: double.infinity,
    child: Padding(
      padding: EdgeInsets.fromLTRB(size.width * 0.03,
          size.width * 0.1, size.width * 0.03, size.width * 0.00),
      child: TextField(
        cursorColor: BaseData.vadenHomeSiyah,
        controller: txtPaletNo,
        textAlign: TextAlign.center,
        decoration: InputDecoration(
            focusedBorder: OutlineInputBorder(
              borderSide: const BorderSide(
                  color: Color.fromARGB(255, 0, 0, 0), width: 2.0),
              borderRadius: BorderRadius.circular(25.0),
            ),
            border: UnderlineInputBorder(),
            labelText: 'Palet No',
            labelStyle: TextStyle(
                color: Colors.black, fontSize: size.width * 0.05),
            filled: true,
            isDense: true,
            fillColor: Colors.white.withOpacity(0.2)),
        onSubmitted: (value) {
          setState(() {
            paletRaporYuklendimi = true;
          });
          seciliPaletRaporGetir();
        },
        onChanged: (text) {},
      ),
    ),
  ),
  Padding(
    padding: EdgeInsets.fromLTRB(size.width * 0.00,
        size.width * 0.08, size.width * 0.00, size.width * 0.00),
    child: SizedBox(
      width: MediaQuery.of(context).size.width,
      child: paletRaporYuklendimi
          ? Center(
              child: Padding(
                padding: EdgeInsets.all(size.width * 0.2),
                child: const CircularProgressIndicator(
                  color: Colors.black,
                ),
              ),
            )
          // 核心修改:用InteractiveViewer包裹DataTable实现缩放
          : InteractiveViewer(
              // 最小缩放比例,防止内容过小
              minScale: 0.5,
              // 最大缩放比例,防止内容过大
              maxScale: 2.5,
              // 允许缩放后内容超出屏幕边界,方便拖动查看完整表格
              boundaryMargin: const EdgeInsets.all(double.infinity),
              child: DataTable(
                dataRowHeight: size.width * 0.4,
                columns: const <DataColumn>[
                  DataColumn(
                    label: Text(
                      'Palet No',
                      style: TextStyle(
                          fontWeight: FontWeight.w900, fontSize: 30),
                    ),
                  ),
                  DataColumn(
                    label: Text(
                      'Paket No',
                      style: TextStyle(
                          fontWeight: FontWeight.w900, fontSize: 30),
                    ),
                  ),
                  DataColumn(
                    label: Text(
                      'Tarih',
                      style: TextStyle(
                          fontWeight: FontWeight.w900, fontSize: 30),
                    ),
                  ),
                  DataColumn(
                    label: Text(
                      'Hareket Tip',
                      style: TextStyle(
                          fontWeight: FontWeight.w900, fontSize: 30),
                    ),
                  ),
                  DataColumn(
                    label: Text(
                      'Hücre Kodu',
                      style: TextStyle(
                          fontWeight: FontWeight.w900, fontSize: 30),
                    ),
                  ),
                  DataColumn(
                    label: Text(
                      'Hareket Turu',
                      style: TextStyle(
                          fontWeight: FontWeight.w900, fontSize: 30),
                    ),
                  ),
                  DataColumn(
                    label: Text(
                      'Cari Isim',
                      style: TextStyle(
                          fontWeight: FontWeight.w900, fontSize: 30),
                    ),
                  ),
                ],
                rows: List.generate(filterList.length, (index) {
                  final item = filterList[index];
                  return DataRow(
                    cells: [
                      DataCell(Text(
                        item.PALETNO ?? "",
                        style: const TextStyle(
                            fontWeight: FontWeight.w900, fontSize: 30),
                      )),
                      DataCell(Text(
                        item.PAKETNO.toString(),
                        style: const TextStyle(
                            fontWeight: FontWeight.w900, fontSize: 30),
                      )),
                      DataCell(Text(
                        item.TARIH ?? "",
                        style: const TextStyle(
                            fontWeight: FontWeight.w900, fontSize: 30),
                      )),
                      DataCell(item.HAREKETTIPI == "G"
                          ? Text(
                              item.HAREKETTIPI ?? "",
                              style: const TextStyle(
                                  fontWeight: FontWeight.w900,
                                  fontSize: 30,
                                  color: Colors.green),
                            )
                          : Text(
                              item.HAREKETTIPI ?? "",
                              style: const TextStyle(
                                  fontWeight: FontWeight.w900,
                                  fontSize: 30,
                                  color: Colors.red),
                            )),
                      DataCell(Text(
                        item.HUCREKODU ?? "",
                        style: const TextStyle(
                            fontWeight: FontWeight.w900, fontSize: 30),
                      )),
                      DataCell(Text(
                        item.HAREKETTURU ?? "",
                        style: const TextStyle(
                            fontWeight: FontWeight.w900, fontSize: 30),
                      )),
                      DataCell(Text(
                        item.CARIISIM ?? "",
                        style: const TextStyle(
                            fontWeight: FontWeight.w900, fontSize: 30),
                      )),
                    ],
                  );
                }),
              ),
            ),
    ),
  ),
  if (filterList.length > 0)
    Padding(
      padding: EdgeInsets.all(size.width * 0.03),
      child: Text(
        "Listelenen Kayıt Sayısı: " + filterList.length.toString(),
        textAlign: TextAlign.right,
        style: TextStyle(
            color: Colors.green, fontWeight: FontWeight.bold),
      ),
    )
  else
    Text("")
]),

关键参数说明

  • minScale/maxScale:自定义缩放的最小和最大比例,可根据业务需求调整
  • boundaryMargin:设置为EdgeInsets.all(double.infinity)后,缩放后的表格可超出屏幕范围,用户可拖动查看完整内容
  • 若需要让整个页面(包括顶部TextField)都支持缩放,只需把整个ListView包裹在InteractiveViewer中即可

内容的提问来源于stack exchange,提问作者B.Taha TIĞLIOĞLU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:14:59