Related
I want to show the snack bar or Dialog on any screen in the Flutter app, anyone knows the way for that ?
For example.. let's say, I receive a notification when the user is in-app, on any screen in-app. How can I display the snack bar message in that situation regardless of which screen the user is currently on?
You can do something like that :
pip_flutter: ^0.0.3
Example:
import 'package:flutter/material.dart';
import 'package:pip_flutter/pipflutter_player.dart';
import 'package:pip_flutter/pipflutter_player_configuration.dart';
import 'package:pip_flutter/pipflutter_player_controller.dart';
import 'package:pip_flutter/pipflutter_player_data_source.dart';
import 'package:pip_flutter/pipflutter_player_data_source_type.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.pink,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Picture in Picture Mode'),
),
body: Center(
child: InkWell(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => PictureInPicturePage()));
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Center(
child: Container(
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8.0),
decoration: BoxDecoration(color: Colors.pink,borderRadius: BorderRadius.circular(12.0)),
child: const Text(
'Picture in Picture Mode',
style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 16),
),
),
),
),
),
),
);
}
}
class PictureInPicturePage extends StatefulWidget {
#override
_PictureInPicturePageState createState() => _PictureInPicturePageState();
}
class _PictureInPicturePageState extends State<PictureInPicturePage> {
late PipFlutterPlayerController pipFlutterPlayerController;
final GlobalKey pipFlutterPlayerKey = GlobalKey();
#override
void initState() {
PipFlutterPlayerConfiguration pipFlutterPlayerConfiguration =
const PipFlutterPlayerConfiguration(
aspectRatio: 16 / 9,
fit: BoxFit.contain,
);
PipFlutterPlayerDataSource dataSource = PipFlutterPlayerDataSource(
PipFlutterPlayerDataSourceType.network,
'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
);
pipFlutterPlayerController =
PipFlutterPlayerController(pipFlutterPlayerConfiguration);
pipFlutterPlayerController.setupDataSource(dataSource);
pipFlutterPlayerController
.setPipFlutterPlayerGlobalKey(pipFlutterPlayerKey);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Picture in Picture player"),
leading: IconButton(onPressed: (){
Navigator.of(context).pop();
}, icon: const Icon(Icons.arrow_back_ios,color: Colors.white,)),
),
body: Column(
children: [
const SizedBox(height: 20),
Flexible(
flex: 1,
fit: FlexFit.loose,
child: AspectRatio(
aspectRatio: 16 / 9,
child: PipFlutterPlayer(
controller: pipFlutterPlayerController,
key: pipFlutterPlayerKey,
),
),
),
Container(
margin: const EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
InkWell(
child: Container(
width: MediaQuery.of(context).size.width * 0.4,
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8.0),
decoration: BoxDecoration(color: Colors.pink,borderRadius: BorderRadius.circular(12.0)),
child: const Center(child: Text("Show PiP",style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),))),
onTap: () {
pipFlutterPlayerController
.enablePictureInPicture(pipFlutterPlayerKey);
},
),
InkWell(
child: Container(
width: MediaQuery.of(context).size.width * 0.4,
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8.0),
decoration: BoxDecoration(color: Colors.pink,borderRadius: BorderRadius.circular(12.0)),
child: Center(child: const Text("Disable PiP",style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),))),
onTap: () async {
pipFlutterPlayerController.disablePictureInPicture();
},
),
],
),
),
],
),
);
}
}
I'm trying to achieve a scroll section containing a row which contains a list view and a details view. The goal is to have one scroll view that scroll both the list and the details view. From an UX perspective, both sections should always be seen, such as if one section is much larger than the other, the smaller section will always be seen.
I'm under the impression that this is the use case for NestedScrollView so ultimately what I'm after is something using it. I know it's possible to sync multiple controllers together programmatically, but I'm hoping for something simpler.
Like the following (this is just an example, my screen does not look anything like this):
The code below is where I got to. It throws an error that scrollController is used in multiple places. Another problem is that scrolling the left side till the end does not scroll the right side till the end.
Here is a full repro:
https://github.com/cedvdb/flutter_repros/tree/double_scroll
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverAppBar(
title: const Text('example'),
)
],
body: Row(
children: [
SizedBox(
width: 500,
child: ListView.builder(
itemCount: 30,
itemBuilder: (context, index) => ListTile(
title: Text('tile $index'),
),
),
),
const SizedBox(
width: 20,
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Container(height: 500, color: Colors.yellow),
Container(height: 500, color: Colors.orange),
Container(height: 500, color: Colors.blue),
Container(height: 500, color: Colors.yellow),
],
),
),
),
const SizedBox(
width: 20,
),
],
),
),
);
}
}
Try this one, it works for me.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverAppBar(
title: const Text('example'),
)
],
body: SingleChildScrollView (
child: Row(
crossAxisAlignment : CrossAxisAlignment.start,
children: [
SizedBox(
width: 500,
child: ListView.builder(
itemCount: 30,
shrinkWrap: true,
itemBuilder: (context, index) => ListTile(
title: Text('tile $index'),
),
),
),
const SizedBox(
width: 20,
),
Expanded(
// child: SingleChildScrollView(
child: Column(
children: [
Container(height: 500, color: Colors.yellow),
Container(height: 500, color: Colors.orange),
Container(height: 500, color: Colors.blue),
Container(height: 500, color: Colors.yellow),
],
// ),
),
),
const SizedBox(
width: 20,
),
],
),
),
),
);
}
}
So basically when you are using one scrollview with two scrollable widgets flutter can't decide how to draw the scrollbar. so if you disable scrollbar then your code will stop throwing error(if you are okay with no scrollbar it will scroll but no scrollbars will be displayed).
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
//this line added here!
scrollBehavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverAppBar(
title: const Text('example'),
)
],
body: Row(
children: [
SizedBox(
width: 500,
child: ListView.builder(
itemCount: 30,
itemBuilder: (context, index) => ListTile(
title: Text('tile $index'),
),
),
),
const SizedBox(
width: 20,
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Container(height: 500, color: Colors.yellow),
Container(height: 500, color: Colors.orange),
Container(height: 500, color: Colors.blue),
Container(height: 500, color: Colors.yellow),
],
),
),
),
const SizedBox(
width: 20,
),
],
),
),
);
}
}
What i understood is that there are two scrolls and items from one point to items in the other and you need a method to move the second one on a event (scroll) but by the example having different size lines i asume it's some kind of cursor in a array thing; if that is what you need you only have to implement the exact movement you want, the example just scrolls to the place of the line you click
import 'package:flutter/material.dart';
import 'dart:math';
void main() => runApp(const App());
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Page_Home(),
),
);
}
}
class List_Element {
String title;
String content;
final GlobalKey _key;
List_Element(
this.title,
this.content,
) : this._key = GlobalKey();
GlobalKey get_key() => _key;
}
class Page_Home extends StatefulWidget {
const Page_Home({Key? key}) : super(key: key);
#override
_Page_Home createState() => _Page_Home();
}
class _Page_Home extends State<Page_Home> {
late List<List_Element> elements;
final scroll_view = ScrollController();
double _get_heigth(key) {
final size = key.currentContext!.size;
if (size != null) {
return size.height;
} else {
return 0;
}
}
Widget build_list(BuildContext ctx) {
return SingleChildScrollView(
child: Column(
children: List<Widget>.generate(elements.length, (i) {
return InkWell(
onTap: () {
double pos = 0;
for (int e = 0; e < i; e++) {
pos += _get_heigth(elements[e].get_key());
}
scroll_view.animateTo(
pos,
duration: const Duration(seconds: 1),
curve: Curves.easeIn,
);
print("Jump $i to $pos");
},
child: Container(
margin: EdgeInsets.only(top: 10),
color: Colors.blueGrey,
width: double.infinity,
height: 30,
child: Center(child: Text("Line ${elements[i].title}")),
));
}),
),
);
}
Widget build_element_view(BuildContext ctx) {
return SingleChildScrollView(
controller: scroll_view,
child: Column(
children: List<Widget>.generate(elements.length, (i) {
return Container(
margin: EdgeInsets.only(top: 10),
color: Colors.blueGrey,
width: double.infinity,
child: Text(elements[i].content),
key: elements[i].get_key(),
);
}),
),
);
}
#override
void dispose() {
scroll_view.dispose();
super.dispose();
}
#override
Widget build(BuildContext ctx) {
Size vsize = MediaQuery.of(ctx).size;
this.elements = List<List_Element>.generate(
30,
(i) => List_Element(
i.toString(),
i.toString() * Random().nextInt(300),
));
return ConstrainedBox(
constraints: BoxConstraints.tight(vsize),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(
width: vsize.width * 0.4,
height: vsize.height,
child: this.build_list(ctx),
),
SizedBox(
width: vsize.width * 0.5,
height: vsize.height,
child: this.build_element_view(ctx),
),
],
),
);
}
}
I could not get the behavior I wanted (and I'm not even sure it makes sens anymore) so I made 2 scroll in the row:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController left = ScrollController();
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverAppBar.medium(
title: const Text('example'),
),
],
body: LayoutBuilder(builder: (context, constraints) {
return Row(
children: [
Container(
color: Colors.greenAccent,
height: constraints.maxHeight,
width: 400,
child: MyListView(controller: left),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Container(height: 500, color: Colors.yellow),
Container(height: 500, color: Colors.orange),
Container(height: 500, color: Colors.blue),
Container(height: 500, color: Colors.yellow),
],
),
),
),
],
);
}),
),
);
}
}
class MyListView extends StatelessWidget {
final ScrollController? controller;
const MyListView({Key? key, this.controller}) : super(key: key);
#override
Widget build(BuildContext context) {
return CustomScrollView(
controller: controller,
slivers: [
SliverFixedExtentList(
itemExtent: 60,
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(
title: Text('tile $index'),
),
childCount: 30),
),
const SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text('secon list'),
),
),
SliverFixedExtentList(
itemExtent: 60,
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(
title: Text('tile $index'),
),
childCount: 30,
),
),
],
);
}
}
I am attempting fit a row of widgets to a container, but it seems to overflow when i set the property of the mainaxisalignment to MainAxisAlignment.spaceBetween. This causes the row (font awesome icon) to overflow the width of the container. I'm not sure how to fit the row to the width of the container. I am getting render errors when trying to wrap the row with an expanded widget.
Not sure where i am going wrong.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
//clipBehavior: Clip.none,
color: Colors.blue,
child:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Hello'
),
Icon(FontAwesomeIcons.solidMoneyBillAlt)
],
),
),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Current result:
Better answer use FaIcon widget Instead of Icon widget
Row(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Hello'),
FaIcon(
FontAwesomeIcons.solidMoneyBillAlt,
size: 50,
)
],
)
Try like this
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text('Hello'),
),
Container(
width: 50,
child: Icon(
FontAwesomeIcons.solidMoneyBillAlt,
// size: 30,
),
)
],
)
SAmpleCode
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
//clipBehavior: Clip.none,
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text('Hello'),
),
Container(
width: 50,
child: Icon(
FontAwesomeIcons.solidMoneyBillAlt,
// size: 30,
),
)
],
),
),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Try below code hope its help to you. Add your icon with padding.
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Hello'),
Padding(
padding: EdgeInsets.only(right: 12.0),
child: Icon(Icons.money),
),
],
),
),
),
Result Screen->
I am using flutter's latest(null safety) version and I created a constructor.
This code does not show anything on the screen. Why can't I see icons and text?
import 'package:flutter/material.dart';
import 'input_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.lightBlue[300],//app bar ın rengi
scaffoldBackgroundColor: Colors.lightBlue[300],//scfold un body si
),
home: InputPage(),
);
}
}
following code input_page.dart
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class InputPage extends StatefulWidget {
#override
_InputPageState createState() => _InputPageState();
}
class _InputPageState extends State<InputPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'YAŞAM BEKLENTİSİ',
style: TextStyle(color: Colors.black54),
),
centerTitle: true,
),
body: Column(
children: <Widget>[
Expanded(
child: Row(
children: [
Expanded(
child: MyContainer(),
),
Expanded(
child: MyContainer(),
),
],
),
),
Expanded(
child: MyContainer(),
),
Expanded(
child: MyContainer(),
),
Expanded(
child: Row(
children: [
Expanded(
child: MyContainer(
child: Column(
children: <Widget>[
Icon(
(FontAwesomeIcons.venus),
size: 50,
color: Colors.black54,
),
Text("KADIN"),
],
),
),
),
Expanded(
child: MyContainer(),
),
],
),
),
],
),
);
}
}
class MyContainer extends StatelessWidget {
final Color color;
final Widget? child;
MyContainer({this.color = Colors.white, this.child});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(12),
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(10), color: color),
);
}
That's because you didn't provide child to your Container.
class MyContainer extends StatelessWidget {
final Color color;
final Widget? child;
MyContainer({this.color = Colors.white, this.child});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(12),
decoration: BoxDecoration(...),
child: child, // <-- Missing
);
}
}
Is it possible to do with flutter?
lot of hashtags came from database. If hashtags length more than 3, that time +10more button there, while we click the button. It will expanded to show all the hashtags. Kindly check my two image, you will get an idea.
First Image
first image
Second Image
second image
Yes, it's possible!
Here is a simple example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> _hashtags = ["Flutter", "Dart", "Google"];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.grey,
height: 50,
child: ListView.builder(
itemCount: _hashtags.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(3.0),
child: Text("#${_hashtags[index]}"),
);
},
),
),
],
),
),
);
}
}
Interactive example
Output example:
You can acheive that by doing this
RichText(
text: TextSpan(
children: controller.hashtagList.value
.map((e) => WidgetSpan(
style: GoogleFonts.quicksand(
color: Colors.blue, fontSize: 16),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'#${e.hashtag}',
),
),
),
)))
.toList()))