成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何在 Flutter 中實現 2D 可滾動的表格,探索 Flutter 中的二維可滾動項,表格解決方案

開發 前端
Flutter 的預構建 widget 具有出色的性能,僅當子視圖位于視圖中時才延遲渲染子視圖,從而提高了性能,但 Flutter 發布了一個新包 two_dimensional_scrollables 來實現在垂直軸和水平軸上滾動的 TableView。

背景

表格是在應用程序中高效組織數據的有用工具。Flutter 的最新更新引入了 TwoDimensionalScrollView 小部件。

TwoDimensionalScrollView 是一個小部件,它結合了 TwoDimensionalScrollable 和 TwoDimensionalViewport 在垂直和水平維度上創建內容的交互式滾動窗格,但直接使用它有點具有挑戰性。

下面是在 Flutter 中實現 2D ScrollView 的演示代碼。

介紹

Flutter 的預構建 widget 具有出色的性能,僅當子視圖位于視圖中時才延遲渲染子視圖,從而提高了性能,但 Flutter 發布了一個新包 two_dimensional_scrollables 來實現在垂直軸和水平軸上滾動的 TableView。

在本教程中,我們將探索這個包來實現一個非常簡單的 Tableview,并了解如何自定義它。

您可以在這里[1]找到完整的源代碼。

執行

添加依賴項

要添加依賴項,請首先打開 pubspec.yaml 文件,然后添加依賴項。

dependencies:
  two_dimensional_scrollables: <latest version>

將 TableView 添加到屏幕

添加 TableView 時,可以使用兩個構造函數:

  • TableView.list :這個與 Flutter 的 ListView 類似。它一次添加所有單元格,并且適用于較短的列表。
  • Tableview.builder :當視圖進入視口時,它會延遲添加子項。非常適合您不想一次加載所有內容的較大列表!

讓我們創建一個簡單的 Tableview 來顯示以下信息。

class Employee {
 final String id;
 final String name;
 final String role;
 final String email;
     Employee({
         required this.id,
         required this.name,
         required this.role,
         required this.email});
 static get getEmployees{
    return [
      Employee(id: '1', name: 'John Doe', role: 'Manager', email: 'john@example.com'),
      Employee(id: '2', name: 'Jane Smith', role: 'Developer', email: 'jane@example.com'),
      Employee(id: '3', name: 'Mike Johnson', role: 'Designer', email: 'mike@example.com'),
      Employee(id: '4', name: 'Emily Brown', role: 'HR Specialist',email: 'emily@example.com'),
      Employee(id: '5', name: 'Alex Lee', role: 'Marketing Analyst', email: 'alex@example.com'),
      Employee(id: '6', name: 'John Doe', role: 'Manager', email: 'john@example.com'),
      Employee(id: '7', name: 'Jane Smith', role: 'Developer', email: 'jane@example.com'),
      Employee(id: '8', name: 'Mike Johnson', role: 'Designer', email: 'mike@example.com'),
      Employee(id: '9', name: 'Emily Brown', role: 'HR Specialist',email: 'emily@example.com'),
      Employee(id: '10', name: 'Alex Lee', role: 'Marketing Analyst', email: 'alex@example.com'),
     ];
  }
}

這是 TableView.builder 的基本示例代碼。

class TwoDimensionalScrollableDemo extends StatelessWidget {
   TwoDimensionalScrollableDemo({super.key});

final  List<Employee> employees = Employee.getEmployees;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Table view Demo"),
      ),
      body: TableView.builder(
          columnCount: 2,
          rowCount: 11,
          columnBuilder: buildTableSpan,
          rowBuilder: buildTableSpan,
          cellBuilder: (BuildContext context, TableVicinity vicinity) {
            return Container(child: Center(child: addText(vicinity)));
          }),
    );
  }

  TableSpan buildTableSpan(int index){
    return TableSpan(extent: FixedTableSpanExtent(50));
  }

  Widget addText(TableVicinity vicinity) {
    if (vicinity.yIndex == 0 && vicinity.xIndex == 0) {
      return const Text("Index");
    } else if (vicinity.yIndex == 0 && vicinity.xIndex == 1) {
      return const Text("name");
    } else if (vicinity.xIndex == 0) {
      return Text(employees[vicinity.yIndex-1].id);
    } else if (vicinity.xIndex == 1) {
      return Text(employees[vicinity.yIndex-1].name);
    }
    return Text("");
  }
}

這對于幾行代碼來說已經相當不錯了,讓我們分解一下 TableView.builder 所需的參數。

  • columnCount :該參數設置表中的列數。
  • rowCount :該參數設置表中的行數。
  • columnBuilder :它是一個幫助定義表中每列的布局和功能的函數。它接受一個整數作為參數,并返回一個 TableSpan ,它構造和配置列。
  • rowbuilder :與 columnBuilder 類似,此函數定義 TableView 中每行的布局和行為。
  • cellBuilder :它處理表中每個單元格的布局。它采用 TableVicinity 參數,其中包含特定單元格的行索引和列索引。這有助于您自定義表格中各個單元格的外觀和行為。

運行上面的代碼,您將看到以下輸出。

圖片圖片

現在,讓我們研究一下 TableView.builder 提供的功能!那么,讓我們看看如何自定義和控制 TableView 并添加更多功能。

TableSpan 表跨度

TableSpan 表示 TableView 中的一行或一列。

添加邊框

TableSpan buildTableSpan(int index) {
  TableSpanDecoration decoration = const TableSpanDecoration(
      border: TableSpanBorder(
          trailing: BorderSide(color: Colors.black),
          leading: BorderSide(color: Colors.black)));
  return  TableSpan(
      extent: const FixedTableSpanExtent(100),
      foregroundDecoration: decoration);
}

TableSpanDecoration 類用于指定 TableSpan 的裝飾。我們可以通過 TableSpanBorder 類中的 border 參數為 TableSpan 添加邊框,該類具有代表行左右邊框和列上下邊框的拖尾和前導屬性。

添加顏色

TableSpan buildTableSpan(int index) {
  TableSpanDecoration decoration =  TableSpanDecoration(
      color: index == 0 ? Colors.grey[300] : null,
      border: const TableSpanBorder(
          trailing: BorderSide(color: Colors.black),
          leading: BorderSide(color: Colors.black)));
  return  TableSpan(
      extent: const FixedTableSpanExtent(100),
      backgroundDecoration: decoration);
}

TableSpanDecoration 中的 color 屬性用于設置 TableSpan 的顏色。

運行代碼,輸出將如下所示

圖片圖片

因為

  • 在 TableView 中,裝飾按特定順序繪制。
  • 首先繪制 mainAxis 的 backgroundDecoration (作為主軸的行或列)。
  • 然后,繪制其他軸上的裝飾。
  • 接下來,繪制跨度內的各個單元格內容。
  • 最后,任何指定的 foregroundDecoration 都會繪制在內容之上。

這里默認的軸是 Axis.vertical ,所以,先繪制列,然后繪制行,邊框與行裝飾重疊,所以,讓我們為前景裝飾添加邊框。

TableSpan buildTableSpan(int index) {
  TableSpanDecoration foreGroundDecoration = const TableSpanDecoration(
      border: TableSpanBorder(
          trailing: BorderSide(color: Colors.black),
          leading: BorderSide(color: Colors.black)));
  TableSpanDecoration backGroundDecoration = TableSpanDecoration(
    color: index == 0 ? Colors.grey[300] : null,
  );
  return TableSpan(
      extent: const FixedTableSpanExtent(100),
      backgroundDecoration: backGroundDecoration,
      foregroundDecoration: foreGroundDecoration);
}

在前景裝飾中添加邊框可確保其呈現在 TableView 中單元格內容的頂部。

圖片圖片

TableSpan.extent

它表示行的高度和列的寬度,TableSpanExtent 有四種類型。

1.FixedTableSpanExtent

具有固定[像素]的跨度。

extent: const FixedTableSpanExtent(50),

圖片圖片

2.FractionTableSpanExtent

它將跨度范圍指定為視口范圍的一部分。它與 Expanded 小部件相同,根據提供的分數占用空間。

extent: const FractionalTableSpanExtent(0.5),

圖片圖片

3.RemainingTableSpanExtent

它指定跨度應占據視口中的剩余空間。

TableSpan buildColumnSpan(int index) {
  TableSpanDecoration decoration =  const TableSpanDecoration(
      border: TableSpanBorder(
          trailing: BorderSide(color: Colors.black),
          leading: BorderSide(color: Colors.black)));
  return TableSpan(
      extent: index==0? FixedTableSpanExtent(100):RemainingTableSpanExtent(), backgroundDecoration: decoration);
}

圖片圖片

4.CombiningTableSpanExtent

它以兩個范圍作為參數,并通過組合器函數運行這兩個范圍的結果。

TableSpan buildRowSpan(int index) {
    TableSpanExtent extent1 = FixedTableSpanExtent(100);
    TableSpanExtent extent2 = FixedTableSpanExtent(100);
    double combiner(double value1, double value2) {
      return value1 + value2;
    }

    TableSpanDecoration foreGroundDecoration = const TableSpanDecoration(
        border: TableSpanBorder(
            trailing: BorderSide(color: Colors.black),
            leading: BorderSide(color: Colors.black)));
    TableSpanDecoration backGroundDecoration = TableSpanDecoration(
      color: index == 0 ? Colors.grey[300] : null,
    );
    if (index == 1) {
      return TableSpan(
          extent: CombiningTableSpanExtent(extent1, extent2, combiner),
          backgroundDecoration: backGroundDecoration,
          foregroundDecoration: foreGroundDecoration);
    }
    return TableSpan(
        extent: const FixedTableSpanExtent(100),
        backgroundDecoration: backGroundDecoration,
        foregroundDecoration: foreGroundDecoration);
  }

圖片圖片

當鼠標指針(按下或不按下按鈕)進入此跨度描述的行或列時觸發。

void Function(PointerEnterEvent)? onEnter

void Function(PointerExitEvent)? onExit

當鼠標指針(按下或未按下按鈕)退出此跨度描述的行或列時,它會觸發。

void Function(PointerExitEvent)? onExit

recognizerFactories

recognizerFactories: <Type, GestureRecognizerFactory>{
  TapGestureRecognizer:
  GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
        () => TapGestureRecognizer(),
        (TapGestureRecognizer t) {
          t.notallow=(TapDownDetails tapdownDetails){
            print(tapdownDetails.localPosition);
          };
          t.notallow=(TapUpDetails tapupDetails){
            print(tapupDetails.localPosition);
          };
        }   
  ),
},

recognizerFactories 是一個映射,其中鍵是手勢類型,值是 GestureRecognizerFactory 的實例。

GestureRecognizerFactoryWithHandlers 有兩個參數。調用時返回 TapGestureRecognizer 實例的函數和初始化 TapGestureRecognizer 并設置事件處理程序以處理特定事件詳細信息的回調函數。

添加填充

padding 屬性用于為每行和每列添加填充。

padding: TableSpanPadding(leading: 10),

向 UI 添加更多列和行

讓我們在 TableView 中顯示來自 Employee 類的更多數據,例如 email 和 role 。

Widget addText(TableVicinity vicinity) {
    if (vicinity.yIndex == 0 && vicinity.xIndex == 0) {
      return const Text("Index");
    } else if (vicinity.yIndex == 0 && vicinity.xIndex == 1) {
      return const Text("name");
    } else if (vicinity.yIndex == 0 && vicinity.xIndex == 2) {
      return const Text("Email");
    } else if (vicinity.yIndex == 0 && vicinity.xIndex == 3) {
      return const Text("Role");
    } else if (vicinity.xIndex == 0) {
      return Text(employees[vicinity.yIndex - 1].id);
    } else if (vicinity.xIndex == 1) {
      return Text(employees[vicinity.yIndex - 1].name);
    } else if (vicinity.xIndex == 2) {
      return Text(employees[vicinity.yIndex - 1].email);
    } else if (vicinity.xIndex == 3) {
      return Text(employees[vicinity.yIndex - 1].role);
    }
    return Text("");
  }
...

      body: TableView.builder(
          mainAxis: Axis.horizontal,
          columnCount: 4,
          rowCount: 21,
          columnBuilder: buildColumnSpan,
          rowBuilder: buildTableSpan,
          cellBuilder: (BuildContext context, TableVicinity vicinity) {
            return Center(child: addText(vicinity));
          }),
...

TableSpan buildColumnSpan(int index) {
  TableSpanDecoration decoration = const TableSpanDecoration(
      border: TableSpanBorder(
          trailing: BorderSide(color: Colors.black),
          leading: BorderSide(color: Colors.black)));
  if (index == 2) {
    return TableSpan(
      extent: const RemainingTableSpanExtent(),
      backgroundDecoration: decoration,
    );
  } else if (index == 3) {
    return TableSpan(
      extent: const FractionalTableSpanExtent(0.5),
      backgroundDecoration: decoration,
    );
  }
  return TableSpan(
      extent: FixedTableSpanExtent(100), backgroundDecoration: decoration);
}

輸出是:

圖片圖片

固定行和列

固定持續出現在 TableView 視口邊緣的特定數量的行和列。

TableView.builder(
...
    pinnedRowCount: 1,
    pinnedColumnCount: 1,
   ),

圖片圖片

滾動細節

ScrollableDetail 允許對小部件的垂直和水平滾動行為進行特定配置。

verticalDetails: ScrollableDetails.vertical(
  reverse: true,
  controller: verticalController,
  physics: const AlwaysScrollableScrollPhysics(),
  decorationClipBehavior: Clip.hardEdge
),

ScrollableDetails 中的 verticalDetails 允許對小部件的垂直滾動行為進行特定配置,它封裝了各種屬性。

verticalDetails: ScrollableDetails.vertical(
  reverse: true,
  controller: verticalController,
  physics: const AlwaysScrollableScrollPhysics(),
  decorationClipBehavior: Clip.hardEdge,
)

以下是屬性的詳細說明:

  • reverse :當設置為 true 時,小部件內的內容向相反方向滾動。
  • controller :指定用于管理和控制滾動行為的 ScrollController 。它允許您滾動到特定位置或收聽滾動偏移量的變化。
  • physics :確定滾動物理的行為。
  • decorationClipBehavior :指定可滾動區域裝飾的剪切行為

cacheExtent 緩存范圍

cacheExtent: 200,

與ListView類似, cacheExtent 是在進入屏幕可見部分之前繪制的區域的大小。

DiagonalDragBehavior 對角線拖動行為

該枚舉允許開發人員指定如何使用 kTouchSlop 處理對角滾動。

結論

在本教程中,我們學習了如何使用 Flutter 中的 two_dimensional_scrollable 實現 Flutter 中的 tableView,我們可以用它做更多的事情并使用它添加更多功能。這是我對 Flutter 中 TableView 的一個小介紹。

圖片翻譯自:https://blog.canopas.com/how-to-implement-2d-scrollable-tableview-in-flutter-a8b0fe703614圖片

參考資料:

[1]這里: https://gist.github.com/cp-sneha-s/d2375b2a624f5650fa3836a84805b15f

責任編輯:武曉燕 來源: 獨立開發者張張
相關推薦

2022-05-31 08:49:02

Flutter應用程序前端

2020-04-18 11:04:35

物聯網工業物聯網技術

2024-12-20 19:38:01

ToB業務狀態轉換

2024-04-19 13:09:26

Flutter樣式TextSpan

2019-04-11 11:15:02

Windows 10Windows非活動窗口

2024-07-03 09:13:26

SwiftUI修飾符框架

2024-06-13 11:43:39

2014-07-29 11:10:26

Ubuntu14.04小技巧

2012-05-08 09:53:56

HTML 5

2021-10-30 19:56:10

Flutter按鈕 Buttons

2024-03-20 12:42:26

數據中心運營商

2022-04-20 11:40:51

元宇宙區塊鏈代幣

2023-11-22 07:47:34

2025-04-11 09:44:23

2017-10-26 21:08:15

Tomcat可插拔SCI

2010-09-02 17:01:04

APC

2021-02-23 10:34:51

Java 編程開發

2012-05-25 14:54:49

華為桌面云

2018-10-30 10:40:42

區塊鏈比特幣技術

2020-03-31 21:38:05

物聯網智慧農業機器人
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品欧美一区二区三区麻豆 | 国产成人精品一区二区三区视频 | 久久一起草| 免费一看一级毛片 | 精品久久久久久 | 国产成人精品高清久久 | 亚洲久草视频 | 亚洲最大av网站 | 久久不射网 | 成人欧美一区二区三区黑人孕妇 | 黄色毛片网站在线观看 | 色婷婷久久久久swag精品 | 国产91丝袜在线播放 | 日日夜夜精品免费视频 | 精品国产青草久久久久96 | 精品国产欧美 | 99久久婷婷国产综合精品首页 | 亚洲成人激情在线观看 | 欧美视频1区| 91婷婷韩国欧美一区二区 | 欧美一级在线观看 | 欧美成人久久 | 一级黄色片毛片 | 一级毛片视频在线 | www国产成人免费观看视频,深夜成人网 | 在线看片福利 | 欧美一区二区三区在线观看 | 在线a视频网站 | 不卡一区二区三区四区 | 日韩乱码一二三 | 能看的av | 久久天堂网 | www.色综合 | 亚洲国产成人久久综合一区,久久久国产99 | 国产福利二区 | 国产99久久精品一区二区永久免费 | 九九热在线视频 | 国产影音先锋 | 国产一级精品毛片 | 蜜桃免费一区二区三区 | 久久伊人影院 |