Flutter widget inspired by the classic Desktop-style tab component. Supports customizable themes.
See full documentation at https://caduandrade.github.io/tabbed_view/
Widget inspired by the classic Desktop-style tab component.
License: MIT License
Flutter widget inspired by the classic Desktop-style tab component. Supports customizable themes.
See full documentation at https://caduandrade.github.io/tabbed_view/
Firstly I would like to say thank you for your fantastic widget!
I have a situation where the initial tab I would like open is not always the first tab. I could not find an "initial tab" parameter anywhere or a way to change the tab programmatically to achieve the same result. If you have any advice on how best to do this it would be much appreciated, thank you.
Hi.
I have tried everything and looked at all theming parameters, but I can't work out how to theme the close icon.
I see how to replace the icon data with a different graphic, but I need to be able to specify the colour or tint of the icon separately in the unselected tab state and the selected tab state. There also seems to be a background colour of the icon which is being used as well - or at least the background of the icon is not transparent. I would prefer the icon background to be transparent and only have to set the tint/colour of the icon.
How do I do this? Thanks in advance.
😉
i need to add this for window[tested] to fix MouseRegion
in src\tabbed_button_widget.dart
import 'package:flutter/rendering.dart';
return MouseRegion(
cursor: SystemMouseCursors.click,
onEnter: _onEnter,
onExit: _onExit,
child: GestureDetector(child: icon, onTap: onPressed));
}
If we were using the Flutter version 3.4.0-36.0.pre.5 on channel master and it caused the build error below :
""flutter-build": Error: 'MenuThemeData' is imported from both 'package:flutter/src/material/menu_theme.dart' and 'package:tabbed_view/src/theme/menu_theme_data.dart'."
So we revert back the flutter version to stable (Flutter 3.3.3 • channel stable • https://github.com/flutter/flutter.git) , then it's working without any issues.
So the issue is once the new code get merged into the stable version we will face the same issue again with tabbed_view ?
Is there complete sample code to make drag and drop work?
I have implemented drag from the sample code in my project, but I do not see a fully function sample to make drop work
Can you provide this?
It is essential for managing multi view documents for our app on our desktop and tablet view versions so they can be organized like any browser allows.
(project released in production: tipitaka pali reader).
Hi
Just a quick question please.
Is it possible to hide the top tab widget if there is only one tab?
Many Thanks
Garth
Hi,
Thanks for a great product.
Is it possible to change the name on the Tab programmatically please?
and
Is it possible to have a tap listener on the tab even if it is already selected?
Many Thanks
Garth Waters
I want to have one tab's content to be dynamic using StreamBuilder
, but when a new event is emitted the tab's content doesn't change until I switch to another tab and back.
Tried wrapping TabbedView
(which uses contentBuilder
) with StreamBuilder
and also tried wrapping only an individual tab widget with StreamBuilder
, but the result is the same.
so that it can be switched between mobile and desktop versions
mobile on the bottom is better for thumb navigation
desktop with mouse is better on top
Would be nice to add a feature that instead of creating a dropdown on the right when there are too many tabs, to instead create another row of tabs. An option to have maxRows of tabs then do a menu would be nice too.
🙏
Hi, I have another question about TabbedView
if you would be willing to help me out,
I've been trying to implement TabbedView
inside a column and would like it to resize so that the height equals the height of the selected tab content (instead of double.infinity
).
To illustrate:
I extended the example code so that TabbedView
is in a column with another Container. The TabbedView
is constrained to a fixed height and everything works as expected:
class TabbedViewExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false, home: TabbedViewExamplePage());
}
}
class TabbedViewExamplePage extends StatefulWidget {
@override
_TabbedViewExamplePageState createState() => _TabbedViewExamplePageState();
}
class _TabbedViewExamplePageState extends State<TabbedViewExamplePage> {
late TabbedViewController _controller;
@override
void initState() {
super.initState();
List<TabData> tabs = [];
tabs.add(TabData(
text: 'Tab 1',
leading: (context, status) => Icon(Icons.star, size: 16),
content: Padding(child: Text('Hello'), padding: EdgeInsets.all(8))));
tabs.add(TabData(
text: 'Tab 2',
content:
Padding(child: Text('Hello again'), padding: EdgeInsets.all(8))));
tabs.add(TabData(
closable: false,
text: 'TextField',
content: Padding(
child: TextField(
decoration: InputDecoration(
isDense: true, border: OutlineInputBorder())),
padding: EdgeInsets.all(8)),
keepAlive: true));
_controller = TabbedViewController(tabs);
}
@override
Widget build(BuildContext context) {
TabbedView tabbedView = TabbedView(controller: _controller);
Widget w =
TabbedViewTheme(child: tabbedView, data: TabbedViewThemeData.mobile());
return Scaffold(body: Container(child: Column(
children: [
Container(
color: Colors.blue,
child: SizedBox(
width: double.infinity,
height: 400,
child: w
),
),
Expanded(
child: Container(
color: Colors.green,
child: SizedBox(width: double.infinity,),
),
)
],
), padding: EdgeInsets.all(32)));
}
}
The problem occurs when I comment out height: 400
for the SizedBox
around the TabbedView
. I was expecting the TabbedView
to shrink to the size of the content, but instead I get the following error:
The following assertion was thrown during performLayout():
RenderCustomMultiChildLayoutBox object was given an infinite size during layout.
This probably means that it is a render object that tries to be as big as possible, but it was put inside another render object that allows its children to pick their own size.
The nearest ancestor providing an unbounded height constraint is: RenderFlex#c885f relayoutBoundary=up2 OVERFLOWING
... needs compositing
... parentData: offset=Offset(32.0, 32.0) (can use size)
... constraints: BoxConstraints(0.0<=w<=593.8, 0.0<=h<=564.8)
... size: Size(621.8, 576.0)
... direction: vertical
... mainAxisAlignment: start
... mainAxisSize: max
... crossAxisAlignment: center
... verticalDirection: down
The constraints that applied to the RenderCustomMultiChildLayoutBox were: BoxConstraints(w=593.8, 0.0<=h<=Infinity)
The exact size it was given was: Size(593.8, Infinity)
See https://flutter.dev/docs/development/ui/layout/box-constraints for more information.
Please could you let me know if this is a bug in TabbedView or if I just have a bad understanding of the layout system in Flutter and need to revise that? If the latter then and suggestions would be appreciated. Thank you for your time in advance!
lots of people use RTL languages, please add this feature.
is there initialtab for TabContoller like PageView's PageController?.
How can we set a specific tab size so that it does not adjust to the size of the text inside?
+ plus
icon modification . i want Container --> IconData --> to decorate IconCurrently to close a tab, the tab has to be selected and then it can be closed. How can we integrate functionality to close other tabs that are not in focus or selected.
Happy to contribute this if any direction is available.
So it feels a bit less jarring, the way the default tabviews, and tabs in the tabbar widget animate.
I’m assuming the former could be achieved by using a transition widget, but doesn’t seem like the library allow you to be able to pass something like that own currently.
As for the animation between switching tabs, I assume that’s more complicated, based on how it’s done in the native tabbar widget.
Recently, the Flutter team added MenuThemeData class to the material package. This name clashes with your class of the same name.
I have a page call DataPage which is a stateful widget
I added ApiPageData to TabData
TabData(text: "", content: ApiPagedata(), closable: false)
];
I populated three API pages (have multiple forms) in initState.
@override
void initState() {
for (int i = 1; i < 3; i++) {
tabs.add(TabData(
text: "Tab $i",
content: ApiPagedata(),
));
}
_model = TabbedViewController(tabs);
super.initState();
}
my tabbedView
TabbedView tabbedView = TabbedView(
controller: _model,
);
return Scaffold(
body: Container(child: tabbedView, padding: EdgeInsets.all(32)));
example apipagedata
Statefulwidget--ApiPagedata-->column-->forms
What I want is like a web browser each page must be independent , in TabBarView I can do it with AutomaticKeepAliveClientMixin.
Fluent UI has a callback property called
onReorder: (oldIndex, newIndex) {
It would be good if an internal drag drop could handle this.
You might need a switch to allow this in case it would interfere with previous drag implementations.
Every browser has this feature and it is the most basic use cases for drag and drop.
We can implement drag drop (code is on github for tipitaka pali reader)
However, we don't have access to the major part of the "tab". It would be good if the tab label were a Text() widget that gets passed inside . From there we can make it a dragTarget.
However, the best thing to do would be to have a onReorder
Please see this github repo with example
Code for Demo: https://github.com/bdlukaa/fluent_ui
Demo: https://bdlukaa.github.io/fluent_ui/
Look for navigation / tabview
Lastly,
There is an issue with focus.
if you have 3 tabs, and has #1 in focus but wants to drag #3 to #2 spot, it will not work.
the current version of you widget needs to have the tab in focus in order to initiate a dragTarget. It would be good if you gain focus on mousedown.
One should be able to take any tab and move it anywhere despite being in focus or not in focus.
The fluent example implements this well however, we want to do multiple documents at the same time. (split view).
For now, up to 3 documents (tabs) can show content at the same time. We need your widget in order to do that.
In order to run our code, you need to download the db and split it (according to the github readme file).
The dragtarget is the small eye icon (for now). It is not intuitive. We want either reOrder or we want to pass in a Text() widget for the tab instead of string.
Hi,
Thanks for a great product.
I have added a button to the tab via TabButton.
However, I wish to change the color of the Icon when it is clicked. Is this possible please?
Many Thanks
Garth
Sometimes tab_area and content_area are not placed together.
It will be more flexiable if they can be seperated.
When a ListView is used as tab content, list tile colors are not displayed correctly (in fact, not at all) - for example, no list tile gets ListTile.selectedTileColor
when selected. On the other hand, the selection color somehow appears below the content border.
Demo code (replace your example/main.dart with this) displays a non-tabbed ListView on the left and a tabbed one on the right:
import 'package:flutter/material.dart';
import 'package:tabbed_view/tabbed_view.dart';
void main() {
runApp(TabbedViewExample());
}
class TabbedViewExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false, home: TabbedViewExamplePage());
}
}
class TabbedViewExamplePage extends StatefulWidget {
@override
_TabbedViewExamplePageState createState() => _TabbedViewExamplePageState();
}
class _TabbedViewExamplePageState extends State<TabbedViewExamplePage> {
late TabbedViewController _controller;
@override
void initState() {
super.initState();
List<TabData> tabs = [];
tabs.add(TabData(
text: 'Tab 1',
content: listView));
tabs.add(TabData(
text: 'Tab 2',
content: Padding(child: Text('Hello again'), padding: EdgeInsets.all(8))));
_controller = TabbedViewController(tabs);
}
@override
Widget build(BuildContext context) {
TabbedView tabbedView = TabbedView(controller: _controller);
Widget w = TabbedViewTheme(child: tabbedView, data: TabbedViewThemeData.mobile());
return Scaffold(
body: Row(
children: [
Expanded(child: listView), // <== not tabbed
Expanded(child: Container(child: w, padding: EdgeInsets.all(32))), // <== tabbed
],
));
}
Widget get listView {
return ListView.builder(
itemCount: 50,
itemExtent: 100,
itemBuilder: (context, index) {
return ListTile(
selected: index % 2 == 0,
title: Text('$index'),
tileColor: Colors.yellow,
selectedTileColor: Colors.orange, // Selection color
);
},
);
}
}
I am having a bug when adding a new tab after the first one is already opened. Every time I add a new tab when the first tab is selected, the second tab is immediately highlighted, but every other tab added after the second isn't highlighted.
Tested on all desktop platforms (Windows, Macos, Linux), tabbed_view version 1.17.0
mit@mit-System-Product-Name:~$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.0, on Ubuntu 22.04.2 LTS 5.19.0-42-generic,
locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[✗] Chrome - develop for the web (Cannot find Chrome executable at
google-chrome)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 2022.1)
[✓] Android Studio
[✓] VS Code (version 1.77.3)
[✓] Connected device (1 available)
[✓] Network resources
`import 'package:flutter/material.dart';
import 'package:tabbed_view/tabbed_view.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@OverRide
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: TabbedViewExample(),
);
}
}
class TabbedViewExample extends StatelessWidget {
@OverRide
Widget build(BuildContext context) {
return TabbedViewExamplePage();
}
}
class TabbedViewExamplePage extends StatefulWidget {
@OverRide
_TabbedViewExamplePageState createState() => _TabbedViewExamplePageState();
}
class _TabbedViewExamplePageState extends State {
late TabbedViewController _controller;
List tabs = [];
@OverRide
void initState() {
super.initState();
tabs.add(TabData(
text: 'Tab 1',
leading: (context, status) => Icon(Icons.star, size: 16),
content: Text('Hello')));
tabs.add(TabData(text: 'Tab 2', content: Text('Hello again')));
_controller = TabbedViewController(tabs);
}
@OverRide
Widget build(BuildContext context) {
TabbedView tabbedView = TabbedView(controller: _controller);
Widget w =
TabbedViewTheme(child: tabbedView, data: TabbedViewThemeData.mobile());
return Column(
children: [
TextButton(
onPressed: () {
setState(() {
tabs.add(
TabData(text: 'New tab', content: Text('Hello again')));
});
},
child: Text("Add new tab")),
SizedBox(height: 200, width: 500, child: Scaffold(body: w)),
],
);
}
}
`
Mouse cursor is not over second tab.
Hi @caduandrade !
Just started using this package as well, thanks for the hard work and great job at making these libraries!
I'd like to request the ability to make the text title of the tab header a widget.
The use case - I'd like to change the tab title based on some of the tab's content. It can be done easily if the title is a MobX Observer widget which renders a Text.
First of all thanks for the great package. I was hoping to find something regarding this kind of widget on pub.dev and im glad i found it.
However ,i haven't been able to do certain stuff to get consistent with the app i am currently working on (web,and mobile).So i guess the followings are mainly enhancements demands as i wouldn't like to have to modify a fork of your work so as to stay consistent with your upcoming releases
Although if this can be done currently, please point me to the right way to do them without modifying your code:
-customize the textstyle for a tab when it is selected (like changing the weight to bold)
Please help if some of the above queries can currently be done.
Regards
Is it possible to disable close option for tabs?
Since version 1.17.0
I am facing the following issue during build:
docking-1.11.0/lib/src/internal/widgets/docking_tabs_widget.dart(91,9): error GC6690633: No named parameter with the name 'draggableTabBuilder'
The selected guide must be the last one to be drawn. (#5)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.