fluttercommunity / native_widgets

Native Widgets - A new Flutter package for using Android and iOS natively on each platform. Maintainer: @rodydavis
https://fluttercommunity.github.io/native_widgets/
MIT License
92 stars 18 forks source link

NativeTopTabs: Cannot set value in unmodifiable Map #9

Open Liuhuifeng opened 4 years ago

Liuhuifeng commented 4 years ago

The following UnsupportedError was thrown building NativeTopTabs(dirty): Unsupported operation: Cannot set value in unmodifiable Map

rodydavis commented 4 years ago

Is this still happening? Please feel free to submit a PR

fayaz07 commented 3 years ago

Hi @rodydavis , this is still happening.

Issue 1

Because iosTabs is final and the assigned value is const.

final Map<int, Widget> iosTabs = const <int, Widget>{};

Solution 1

Rewriting the above line of code with

Map<int, Widget> iosTabs =  <int, Widget>{};

Issue 2

One more issue here, for material and using TabBar, it requires a controller which is not specified, so it throws the following error

The following assertion was thrown building NativeTopTabs:
No TabController for TabBar.

When creating a TabBar, you must either provide an explicit TabController using the "controller" property, or you must ensure that there is a DefaultTabController above the TabBar.
In this case, there was neither an explicit controller nor a default controller.

If we specify an implicit TabController that doesn't work as it requires a TickerProvider and throws the following error

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building NativeTopTabs(dirty):
'package:flutter/src/animation/animation_controller.dart': Failed assertion: line 277 pos 15: 'vsync != null': is not true.

Solution 2

Either allow the user to pass a TabController instance or wrap TabBar with DefaultTabController as follows

return DefaultTabController(
      length: tabs.length,
      child: TabBar(
        tabs: tabs,
      ),
    );

Enhancement 1

The TabBar isn't making use of the fields onValueChanged, which forces the user to create custom buttons as

NativeTopTabs(
  tabs: [
    FlatButton(
      child: Text('Hello'),
      onPressed: helloTapHandler,
    )
    ...
  ],
)

also the Tab switching won't work if the user just slides the screen, which will eventually change the Tab, but not the Screen (helloTapHandler doesn't get invoked)

Solution 1

To make use of the onValueChanged property as

return DefaultTabController(
  length: tabs.length,
  child: TabBar(
    tabs: tabs,
    onTap: onValueChanged,
  ),
);

Please assign me if you think this resolves the issue, so I can send a PR

Thanks

rodydavis commented 3 years ago

Yes @fayaz07 please make a PR!