Flutter: недопустимые виджеты отключают обнаружение перетаскивания Tabview

У меня есть две вкладки, левая вкладка со списком плиток и правая вкладка без ничего. Пользователь может перетащить экран справа налево или слева направо, чтобы перейти от одной вкладки к другой. На левой вкладке есть список запрещенных плиток, которые имеют только "direction: DismissDirection.startToEnd" (слева направо), так что пользователь все еще может теоретически перетаскивать (справа налево), чтобы перейти на правую вкладку, Однако я считаю, что виджет "Отклоняемый" все еще получает информацию о перетаскивании справа налево, которая отключает перетаскивание TabView для изменения вкладок.

По сути, как мне разрешить обнаружение перетаскивания справа налево только TabView, а не элементом Dismissible?

Если можно дать явное решение / пример с фрагментами кода, я был бы очень признателен за помощь!

Вот паста для вашего файла main.dart:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/semantics.dart';

void main() {
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]);
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: MainPage(),
    );
  }
}

class MainPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage>
    with SingleTickerProviderStateMixin {
  TabController _tabController;
  @override
  void initState() {
    _tabController = TabController(vsync: this, length: 2, initialIndex: 1);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          color: Colors.black,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Expanded(
                child: TabBarView(
                  controller: _tabController,
                  children: <Widget>[
                    TabWithSomething(),
                    TabWithNothing(),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class TabWithNothing extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        child: Text("Swipe from left-to-right!"),
      ),
    );
  }
}

class TabWithSomethingItem implements Comparable<TabWithSomethingItem> {
  TabWithSomethingItem({this.index, this.name, this.subject, this.body});

  TabWithSomethingItem.from(TabWithSomethingItem item)
      : index = item.index,
        name = item.name,
        subject = item.subject,
        body = item.body;

  final int index;
  final String name;
  final String subject;
  final String body;

  @override
  int compareTo(TabWithSomethingItem other) => index.compareTo(other.index);
}

class TabWithSomething extends StatefulWidget {
  const TabWithSomething({Key key}) : super(key: key);

  static const String routeName = '/material/leave-behind';

  @override
  TabWithSomethingState createState() => TabWithSomethingState();
}

class TabWithSomethingState extends State<TabWithSomething> {
  List<TabWithSomethingItem> TabWithSomethingItems;

  void initListItems() {
    TabWithSomethingItems =
        List<TabWithSomethingItem>.generate(10, (int index) {
      return TabWithSomethingItem(
          index: index,
          name: 'Item $index',
          subject: 'Swipe from left-to-right to delete',
          body: "Swipe from right-to-left to go back to old tab");
    });
  }

  @override
  void initState() {
    super.initState();
    initListItems();
  }

  void _handleDelete(TabWithSomethingItem item) {
    setState(() {
      TabWithSomethingItems.remove(item);
    });
  }

  @override
  Widget build(BuildContext context) {
    Widget body;
    body = ListView(
        children:
            TabWithSomethingItems.map<Widget>((TabWithSomethingItem item) {
      return _TabWithSomethingListItem(
        item: item,
        onDelete: _handleDelete,
        dismissDirection: DismissDirection.startToEnd,
      );
    }).toList());

    return body;
  }
}

class _TabWithSomethingListItem extends StatelessWidget {
  const _TabWithSomethingListItem({
    Key key,
    @required this.item,
    @required this.onDelete,
    @required this.dismissDirection,
  }) : super(key: key);

  final TabWithSomethingItem item;
  final DismissDirection dismissDirection;
  final void Function(TabWithSomethingItem) onDelete;

  void _handleDelete() {
    onDelete(item);
  }

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    return Semantics(
      customSemanticsActions: <CustomSemanticsAction, VoidCallback>{
        const CustomSemanticsAction(label: 'Delete'): _handleDelete,
      },
      child: Dismissible(
        key: ObjectKey(item),
        direction: dismissDirection,
        onDismissed: (DismissDirection direction) => _handleDelete(),
        background: Container(
            color: theme.primaryColor,
            child: const ListTile(
                leading: Icon(Icons.delete, color: Colors.white, size: 36.0))),
        child: Container(
          decoration: BoxDecoration(
              color: theme.canvasColor,
              border: Border(bottom: BorderSide(color: theme.dividerColor))),
          child: ListTile(
              title: Text(item.name),
              subtitle: Text('${item.subject}\n${item.body}'),
              isThreeLine: true),
        ),
      ),
    );
  }
}

ОБНОВЛЕНИЕ: я думаю, что мы могли бы изменить файл "disptable.dart", чтобы изменить "TabControlller", но я не уверен, как я мог бы сделать это.

В файле disptable.dart:

...
  void _handleDragUpdate(DragUpdateDetails details) {
    if (!_isActive || _moveController.isAnimating)
      return;

    final double delta = details.primaryDelta;

    if (delta < 0) print(delta);  // thinking of doing something here
...

0 ответов

Другие вопросы по тегам