Related
I am not able to make the texts button work as it have to show different color text names when the button is pressed. I have mentioned the function call too but the result is same.
import 'dart:math';
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 App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const DemoScreen(),
);
}
}
class DemoScreen extends StatefulWidget {
const DemoScreen({Key? key}): super(key:key);
#override
// ignore: library_private_types_in_public_api
_DemoScreenState createState() => _DemoScreenState();
}
class _DemoScreenState extends State<DemoScreen> {
final Random _randomColor=Random();
Color _circleColor=Colors.white70;
String displayText='Type here';
var string=['Red','Green','Blue','Random','Restart','Texts'];
void changeText(){
setState(() {
displayText=string[Random().nextInt(string.length)];
});
}
void restart(){
_circleColor=Colors.white70;
}
void _updateColor(Color color){
setState(() {
_circleColor=color;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Change Color'),
),
body: ListView(
children:[ Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children:[Center(
child:Container(
padding: const EdgeInsets.only(top: 16.0),
height: 200,
width: 200,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _circleColor,
),
),
),
const SizedBox(height: 20),
Row(
mainAxisSize: MainAxisSize.max,
children: [
ElevatedButton(
child: const Text('Red'),
onPressed: (){
setState(() {
_updateColor(Colors.red);
});
},
),
ElevatedButton(
child: const Text('Green'),
onPressed: (){
setState(() {
_updateColor(Colors.green);
});
},
),
ElevatedButton(
child: const Text('Blue'),
onPressed: (){
setState(() {
_updateColor(Colors.blue);
});
},
),
ElevatedButton(
child: const Text('Random'),
onPressed: (){
setState(() {
_circleColor=Color.fromRGBO(_randomColor.nextInt(400),_randomColor.nextInt(200),_randomColor.nextInt(500), 10);
});
},
),
ElevatedButton(
child: const Text('restart'),
onPressed: (){
setState(() {
restart();
});
},
),
],),
ElevatedButton(
onPressed: (){
setState(() {
changeText();
});
},
child: const Text('Texts'),
),
],
),
],
),
);
}
}
I have created all the buttons correctly but I want to know what is the wrong in text button that I cant make it workable.
I have implemented BlocConsumer for listening to the stream, which will trigger the snack bar widget depending on the state event.
The snack bar is getting triggered three times on a single increment event on the third screen and two times on the second screen. How to make it show once every click on both screens I am using the bloc, flutter_bloc package, any suggestion or direction will be helpful, thank you.
class SecondScreen extends StatefulWidget {
const SecondScreen({Key? key, required this.title, required this.color})
: super(key: key);
final String title;
final Color color;
#override
_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
widget.title.toString(),
),
backgroundColor: widget.color,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text('SECOND PAGE', style: Theme.of(context).textTheme.headline4),
const SizedBox(height: 40.0),
const Text(
'You have clicked this many times',
),
const SizedBox(height: 10.00),
BlocConsumer<CounterCubit, CounterState>(
listener: (context, state) {
// show a snackbar everytime the state changes
// this block of code is listening to every event triggering in the state
if (state.wasIncremented == true) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Incremented'),
duration: Duration(milliseconds: 100),
),
);
} else if (state.wasIncremented == false) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Decremented'),
duration: Duration(milliseconds: 100),
),
);
}
},
builder: (context, state) {
return Text(
state.counterValue.toString(),
style: Theme.of(context).textTheme.headline4,
);
},
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FloatingActionButton(
onPressed: () {
// TO DO
BlocProvider.of<CounterCubit>(context).decrement();
},
child: const Icon(Icons.remove),
heroTag: const Text('btn1'),
),
FloatingActionButton(
onPressed: () {
// TO DO
BlocProvider.of<CounterCubit>(context).increment();
},
child: const Icon(Icons.add),
heroTag: const Text('btn2')),
],
),
const SizedBox(height: 50.00),
MaterialButton(
height: 50.00,
minWidth: 200.00,
child: const Text('Navigate to Next Screen'),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => BlocProvider<CounterCubit>.value(
value: BlocProvider.of<CounterCubit>(context),
child: const ThirdScreen(
title: 'Third Screen', color: Colors.amberAccent),
),
),
);
},
),
],
),
),
);
}
}
`Cubit state`
// ignore_for_file: unnecessary_this
part of 'counter_cubit.dart';
// #immutable
// abstract class CounterState {}
class CounterState {
int counterValue;
bool wasIncremented;
CounterState({
required this.counterValue,
required this.wasIncremented,
});
// #override
// List<Object> get props => [this.counterValue, this.wasIncremented];
}
`Cubit`
import 'package:bloc/bloc.dart';
part 'counter_state.dart';
class CounterCubit extends Cubit<CounterState> {
CounterCubit() : super(CounterState(counterValue: 0, wasIncremented: false));
void increment() => emit(
CounterState(counterValue: state.counterValue + 1, wasIncremented: true));
void decrement() => emit(CounterState(
counterValue: state.counterValue - 1, wasIncremented: false));
}
`Bloc is provided here`
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return BlocProvider<CounterCubit>(
create: (BuildContext context) => CounterCubit(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomeScreen(title: 'First Screen', color: Colors.blueAccent),
),
);
}
}
I am making a List App which a list of items followed by a checkBox .Then there is a floating action button with a plus sign .On click of it u get a bottomSheet .In the bottom sheet you can enter your task to the textField .On clicking on the add button the tasks gets added .
The ui Looks like this
I am not able to access tasks List that is defined in the task_screen.dart from add_taskScreen.dart . I am getting the below error despite importing the required files
error: Undefined name 'tasks'. (undefined_identifier at [todoey_flutter] lib\add_task_screen.dart:43)
here is my Code
Main.dart
import 'package:flutter/material.dart';
import 'tasks_screen.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: TaskScreen(),
);
}
}
Task_tile.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class TaskTile extends StatelessWidget {
#override
late final bool isChecked ;
late final String taskTitle;
final Function checkBoxCallBack;
TaskTile({required this.isChecked,required this.taskTitle,required this.checkBoxCallBack});
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(taskTitle,
style:TextStyle(
decoration: isChecked ? TextDecoration.lineThrough:null
),
),
trailing: Checkbox(
value:isChecked,
activeColor:Colors.lightBlueAccent,
onChanged: (newValue) {//onChanged here if we select the check box the value becomes true else it will become false
checkBoxCallBack(newValue);//widget.toggleCheckBoxState(value);
},
)
);
}
}
Task_list.dart
import 'package:flutter/material.dart';
import 'task_title.dart';
import 'Models/task.dart';
class TaskList extends StatefulWidget {
final List<Task> tasks;
TaskList(this.tasks);
#override
State<TaskList> createState() => _TitleListState();
}
class _TitleListState extends State<TaskList> {
#override
Widget build(BuildContext context) {
return ListView.builder(itemBuilder: (context,index){//in the listView Builder index is already defined and gets updated by itself
return TaskTile(
taskTitle:widget.tasks[index].name,
isChecked: widget.tasks[index].isDone,
checkBoxCallBack:(bool checkBoxState){
setState((){
widget.tasks[index].toggleDone() ;
});
}
);
},
itemCount: widget.tasks.length,//max no tasks that can fit in the screen ie..how many ever tasks are there on 'tasks' it will build that many
);
}
}
task.dart
import 'package:flutter/material.dart';
class Task{
late final String name;
late bool isDone;
Task
({required this.name,this.isDone=false});//give a default value to isDone
void toggleDone()
{
isDone = !isDone;
}
}
task_Screen.dart
import 'package:flutter/material.dart';
import 'tasks_list.dart';
import 'add_task_screen.dart';
import 'package:todoey_flutter/Models/task.dart';
class TaskScreen extends StatefulWidget {
const TaskScreen({Key? key}) : super(key: key);
#override
State<TaskScreen> createState() => _TaskScreenState();
}
class _TaskScreenState extends State<TaskScreen> {
List<Task> tasks = [
Task(name: 'Buy milk'),
Task(name: 'Buy eggs'),
Task(name: 'Buy bread'),
];
#override
Widget build(BuildContext context) {
return Scaffold(//Scaffold contains everything
backgroundColor: Colors.lightBlueAccent,
body:Column(
children: [
Container(
padding:const EdgeInsets.only(top:60,left:30,right:30,bottom: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children:const <Widget>[
CircleAvatar(
child: Icon(
Icons.list,
color: Colors.lightBlueAccent,
size:30.0,
),
backgroundColor:Colors.white,
radius:30,
),
SizedBox(height:10),
Text(
'Todoey',
style:TextStyle(
color:Colors.white,
fontSize: 50,
fontWeight: FontWeight.w700,
)
),
Text('12 Tasks',
style:TextStyle(
color:Colors.white,
fontSize: 18,
)
),
]
),
),
Expanded(
child: Container(//designing the white part of the todoey
padding:const EdgeInsets.symmetric(horizontal: 20),
height:300,
decoration: const BoxDecoration(
color:Colors.white,
borderRadius: BorderRadius.only(
topLeft:Radius.circular(20.0),
topRight:Radius.circular(20.0),
),
),
child: TaskList(tasks),
),
),
],
),
floatingActionButton: FloatingActionButton(
backgroundColor:Colors.lightBlueAccent,
child: const Icon(
Icons.add,
),
onPressed: (){ //call the bottomSheet in builder
showModalBottomSheet(builder:(context)=>AddTaskScreen(
(newTaskTitle)
{
setState(){
tasks.add(Task(name:newTaskTitle));
}
}), context: context);//to create bottom drawer widget on pressing the button a new pop up appears at the bottom
},
),
);
}
}
add_Task_Screen.dart
import 'package:flutter/material.dart';
import 'task_title.dart';
import 'tasks_list.dart';
import 'tasks_screen.dart';
import 'package:todoey_flutter/Models/task.dart';
class AddTaskScreen extends StatelessWidget {
late String newTaskTitle;
final Function addTaskCallBack;
AddTaskScreen( this.addTaskCallBack, {Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
//color:const Color(0xff757575),//you cant add color 2 times it will throw an exception
decoration:const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft:Radius.circular(20.0) ,topRight:Radius.circular(20.0)),
),
child:Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children:[
const Center(
child: Text('Add Task',
style: TextStyle(
fontSize:30.0,
color:Colors.lightBlueAccent,
),
),
),
TextField(
autofocus: true,
autocorrect: true,
textAlign: TextAlign.center,
onChanged: (newText){
newTaskTitle = newText;
},
),
FlatButton(
onPressed: (){
print(newTaskTitle);
tasks.add(name:newTaskTitle);//here is the error
},
child: const Text('Add'),
color: Colors.lightBlueAccent,
)
]
)
),
);
}
}
In task_screen.dart create a function like this
void _handleAddTask(String _name)=>setState(()=>tasks.add(Task(name: _name))));
Then modify showModalBottomSheet to look like this
showModalBottomSheet(builder:(context)=>AddTaskScreen(_handleAddTask,"Add task"), context: context);},),);}}
In add_Task_Screen.dart, modify
AddTaskScreen( this.addTaskCallBack, {Key? key}) : super(key: key); to this
AddTaskScreen( this.addTaskCallBack, this.newTaskTitle, {Key? key}) : super(key: key);
create a TextEditingController for your TextField and pass it to it like this
TextField(
autofocus: true,
controller: _textFieldController,
autocorrect: true,
textAlign: TextAlign.center,
onChanged: (newText){
newTaskTitle = newText;
},
),
Finally, in the onPress of Add button, modify it to something like this:
FlatButton(
onPressed: (){
print(newTaskTitle);
addTaskCallBack(_textFieldController.text);
},
child: const Text('Add'),
color: Colors.lightBlueAccent,
)
The tasks list does not exist in the child widget. You can access the widget via the callback method you provided.
Refactor your FlatButton to look like this:
FlatButton(
onPressed: () {
addTaskCallBack(newTaskTitle);
},
child: const Text('Add'),
color: Colors.lightBlueAccent,
)
I want to pass data onclick of the listview items from one screen to another. All screen has bottom navigation bar with end drawer. Tried to pass data from second screen to details screen but was unsuccessful as there is no Navigator used. Anyone can help me with this? Following is the implemented code
bottom_nav_bar.dart
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'Utility.dart';
import 'main.dart';
class CustomAnimatedBottomBar extends StatelessWidget {
CustomAnimatedBottomBar({
Key? key,
this.selectedIndex = ScreenType.home,
this.showElevation = true,
this.iconSize = 24,
this.backgroundColor,
this.itemCornerRadius = 40,
this.animationDuration = const Duration(milliseconds: 270),
this.mainAxisAlignment = MainAxisAlignment.spaceBetween,
required this.items,
required this.onItemSelected,
this.curve = Curves.linear,
}) : assert(items.length >= 2 && items.length <= 5),
super(key: key);
final ScreenType selectedIndex;
final double iconSize;
final Color? backgroundColor;
final bool showElevation;
final Duration animationDuration;
final List<BottomNavyBarItem> items;
final ValueChanged<ScreenType> onItemSelected;
final MainAxisAlignment mainAxisAlignment;
final double itemCornerRadius;
final Curve curve;
#override
Widget build(BuildContext context) {
final bgColor = backgroundColor ?? Theme.of(context).bottomAppBarColor;
return Container(
decoration: BoxDecoration(
color: bgColor,
boxShadow: [
if (showElevation)
const BoxShadow(
color: Colors.black12,
blurRadius: 2,
),
],
),
child: SafeArea(
child: Container(
width: double.infinity,
height: kToolbarHeight,
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 8),
child: Row(
mainAxisAlignment: mainAxisAlignment,
children: items.map((item) {
var index = item;
return GestureDetector(
onTap: () => onItemSelected(index.screenType),
child: _ItemWidget(
item: item,
iconSize: iconSize,
isSelected: index.screenType == selectedIndex,
backgroundColor: bgColor,
itemCornerRadius: itemCornerRadius,
animationDuration: animationDuration,
curve: curve,
),
);
}).toList(),
),
),
),
);
}
}
class _ItemWidget extends StatelessWidget {
final double iconSize;
final bool isSelected;
final BottomNavyBarItem item;
final Color backgroundColor;
final double itemCornerRadius;
final Duration animationDuration;
final Curve curve;
const _ItemWidget({
Key? key,
required this.item,
required this.isSelected,
required this.backgroundColor,
required this.animationDuration,
required this.itemCornerRadius,
required this.iconSize,
this.curve = Curves.linear,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Semantics(
container: true,
selected: isSelected,
child: AnimatedContainer(
width: isSelected ? 130 : 50,
height: double.maxFinite,
duration: animationDuration,
curve: curve,
decoration: BoxDecoration(
color:
isSelected ? item.activeColor.withOpacity(0.2) : backgroundColor,
borderRadius: BorderRadius.circular(itemCornerRadius),
),
child: Container(
width: isSelected ? 130 : 50,
padding: EdgeInsets.symmetric(horizontal: 10),
child: Row(
// mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
IconTheme(
data: IconThemeData(
size: iconSize,
color: isSelected
? item.activeColor.withOpacity(1)
: item.inactiveColor == null
? item.activeColor
: item.inactiveColor,
),
child: item.icon,
),
if (isSelected)
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 4),
child: DefaultTextStyle.merge(
style: TextStyle(
color: item.activeColor,
fontWeight: FontWeight.bold,
),
maxLines: 1,
textAlign: item.textAlign,
child: item.title,
),
),
),
],
),
),
),
);
}
}
class BottomNavyBarItem {
BottomNavyBarItem({
required this.screenType,
required this.icon,
required this.title,
this.activeColor = Colors.blue,
this.textAlign,
this.inactiveColor,
});
final ScreenType screenType;
final Widget icon;
final Widget title;
final Color activeColor;
final Color? inactiveColor;
final TextAlign? textAlign;
}
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_app/FifthScreen.dart';
import 'package:flutter_app/details_screen.dart';
import 'package:flutter_app/profile_screen.dart';
import 'package:flutter_app/secondPage.dart';
import 'ThirdPage.dart';
import 'Utility.dart';
import 'bottom_nav_bar.dart';
import 'firstpage.dart';
import 'fourthPage.dart';
import 'home_screen.dart';
import 'message_screen.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();
}
enum ScreenType {
firstScreen,
secondScreen,
thirdScreen,
forthScreen,
fifthScreen,
detailsScreen,
home,
messages,
profile
}
class _MyHomePageState extends State<MyHomePage> {
ScreenType _screenType = ScreenType.home;
final _inactiveColor = Colors.grey;
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: getTitle(_screenType),
),
endDrawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('First Screen'),
onTap: (){onTabTapped(ScreenType.firstScreen);
Navigator.of(context).pop();
},
),
ListTile(
title: Text('Second Screen'),
onTap:(){onTabTapped(ScreenType.secondScreen);
Navigator.of(context).pop();
},
),
ListTile(
title: Text('Third Screen'),
onTap: (){onTabTapped(ScreenType.thirdScreen);
Navigator.of(context).pop();
},
),
],
),
),
body: _body(_screenType),
bottomNavigationBar: _buildBottomBar(),
);
}
Widget _body(ScreenType screenType) {
switch (screenType) {
case ScreenType.firstScreen:
return FirstScreen(
navigateScreen: (screenType) => onTabTapped(screenType),
);
case ScreenType.secondScreen:
return SecondScreen(
onClickList: (model){
setState(() {
_screenType = ScreenType.detailsScreen;
});
},
);
case ScreenType.thirdScreen:
return const ThirdScreen();
case ScreenType.forthScreen:
return const ForthScreen();
case ScreenType.home:
return const HomeScreen();
case ScreenType.messages:
return const MessagesScreen();
case ScreenType.profile:
return const ProfileScreen();
case ScreenType.fifthScreen:
return const FifthScreen();
case ScreenType.detailsScreen:
return DetailsScreen();
}
}
Widget _buildBottomBar() {
return CustomAnimatedBottomBar(
backgroundColor: Colors.black,
selectedIndex: _screenType,
showElevation: true,
itemCornerRadius: 24,
curve: Curves.easeIn,
onItemSelected: onTabTapped,
items: <BottomNavyBarItem>[
BottomNavyBarItem(
screenType: ScreenType.home,
icon: Icon(Icons.apps),
title: Text('Home'),
activeColor: Colors.green,
inactiveColor: _inactiveColor,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
screenType: ScreenType.messages,
icon: Icon(Icons.message),
title: Text('Messages'),
activeColor: Colors.purpleAccent,
inactiveColor: _inactiveColor,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
screenType: ScreenType.profile,
icon: Icon(Icons.account_circle_rounded),
title: Text('Profile'),
activeColor: Colors.pink,
inactiveColor: _inactiveColor,
textAlign: TextAlign.center,
),
],
);
}
void onTabTapped(ScreenType screenType) {
if ((_scaffoldKey.currentState ?? ScaffoldState()).isEndDrawerOpen) {
(_scaffoldKey.currentState ?? ScaffoldState()).openEndDrawer();
}
setState(() {
_screenType = screenType;
});
}
Widget getTitle(ScreenType screenType) {
switch (screenType) {
case ScreenType.firstScreen:
return Text("First Screen");
case ScreenType.secondScreen:
return Text("Second Screen");
case ScreenType.thirdScreen:
return Text("Third Screen");
case ScreenType.forthScreen:
return Row(
children: [
IconButton(onPressed: (){
onTabTapped(ScreenType.firstScreen);
}, icon: Icon(Icons.arrow_back_ios)),
Text("Fourth Screen"),
],
);
case ScreenType.detailsScreen:
return Text("Details Screen");
case ScreenType.home:
return Text("Home");
case ScreenType.messages:
return Text("Message");
case ScreenType.profile:
return Text("Profile");
case ScreenType.fifthScreen:
// TODO: Handle this case.
return Text("Fifth Sceen");
break;
}
}
}
second_page.dart
import 'package:flutter/material.dart';
typedef OnClickList(Model);
class SecondScreen extends StatefulWidget {
// final VoidCallback voidCallback;
final OnClickList onClickList;
const SecondScreen({Key? key, required this.onClickList}) : super(key: key);
#override
_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
#override
Widget build(BuildContext context) {
List<Model> items = [
Model(text: "Text 1 to next screen"),
Model(text: "Text 2 to next screen"),
Model(text: "Text 3 to next screen"),
];
return Container(
child: Center(
child: Column(
children: [
Text("Second Screen"),
ListView.builder(
itemCount: items.length,
shrinkWrap: true,scrollDirection: Axis.vertical,
itemBuilder: (context, index){
Model model = items[index];
return GestureDetector(
onTap: (){
widget.onClickList(model.text);
},
child: Card(
child: Text("${items[index].text}"),
),
);
})
],
),
),
);
}
}
class Model{
String text;
Model({required this.text});
}
details_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_app/secondPage.dart';
class DetailsScreen extends StatefulWidget {
final Model? model;
const DetailsScreen({Key? key, this.model}):super(key:key);
#override
_DetailsScreenState createState() => _DetailsScreenState();
}
class _DetailsScreenState extends State<DetailsScreen> {
#override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Text(widget.model!.text.toString()),
),
);
}
}
first_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_app/main.dart';
typedef NavigateScreen(ScreenType);
class FirstScreen extends StatefulWidget {
const FirstScreen({
Key? key,
required this.navigateScreen,
}) : super(key: key);
final NavigateScreen navigateScreen;
#override
_FirstScreenState createState() => _FirstScreenState();
}
class _FirstScreenState extends State<FirstScreen> {
#override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Flex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("First Screen"),
ElevatedButton(
onPressed: () => widget.navigateScreen(ScreenType.forthScreen),
child: Text("Go To Forth Screen"),
),
ElevatedButton(
onPressed: () => widget.navigateScreen(ScreenType.fifthScreen),
child: Text("Go To Fifth Screen"),
),
],
),
),
);
}
}
To pass data from second screen to details screen:
Add a variable in homepage state which can take content clicked from second screen.
class _MyHomePageState extends State<MyHomePage> {
ScreenType _screenType = ScreenType.home;
final _inactiveColor = Colors.grey;
Model? fromSecond;
…….
}
Change onClickList implementation and switch case.
Widget _body(ScreenType screenType) {
switch (screenType) {
case ScreenType.firstScreen:
return FirstScreen(
navigateScreen: (screenType) => onTabTapped(screenType),
);
case ScreenType.secondScreen:
return SecondScreen(
onClickList: (model) {
fromSecond = model;
setState(() {
_screenType = ScreenType.detailsScreen;
});
},
);
……..
…….
case ScreenType.detailsScreen:
{
if(fromSecond!=null) {
return DetailsScreen(model: fromSecond);
} else {
return DetailsScreen();
}
}
………..
……….
}
On SecondScreen make gesture detector return model to onClickList callback.
…………
…………
return GestureDetector(
onTap: (){
widget.onClickList(model);
},
child: Card(
child: Text("${items[index].text}"),
),
);
…….
…….
So I was trying to make a feature where when we click an icon button it will change the video path. It will change the video path using string. I was using a print("$videoname"), to make sure the string changes, and it does. But it still doesn't work, with the videoplayercontroller.assets():
Here's the code that I was trying to make
String videoname="Video/Intro.mp4";
Container(
child:Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ChewieListItem(
videoPlayerController: VideoPlayerController.asset(videoname),
looping: false,
),
Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
height: 100.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
IconButton(
icon:Icon(Icons.people),
onPressed: (){
videoname="Video/Intro.mp4";
print("$videoname");
},
),
IconButton(
icon:Icon(Icons.personal_video),
onPressed: (){
videoname="Video/Intro1.mp4";
print("$videoname");
},
),
],
),
),
)
You can copy paste run full code below
Step 1: Use key: UniqueKey() in ChewieListItem
Step 2: Use setState in onPressed
code snippet
ChewieListItem(
key: UniqueKey(),
videoPlayerController: VideoPlayerController.asset(videoname),
looping: false,
),
IconButton(
icon: Icon(Icons.people),
onPressed: () {
setState(() {
videoname = "Video/Intro.mp4";
print("$videoname");
});
},
),
IconButton(
icon: Icon(Icons.personal_video),
onPressed: () {
setState(() {
videoname = "Video/Intro1.mp4";
print("$videoname");
});
},
),
working demo
full code
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
class ChewieListItem extends StatefulWidget {
// This will contain the URL/asset path which we want to play
final VideoPlayerController videoPlayerController;
final bool looping;
ChewieListItem({
#required this.videoPlayerController,
this.looping,
Key key,
}) : super(key: key);
#override
_ChewieListItemState createState() => _ChewieListItemState();
}
class _ChewieListItemState extends State<ChewieListItem> {
ChewieController _chewieController;
#override
void initState() {
super.initState();
print("ChewieListItem initState");
// Wrapper on top of the videoPlayerController
_chewieController = ChewieController(
videoPlayerController: widget.videoPlayerController,
aspectRatio: 16 / 9,
// Prepare the video to be played and display the first frame
autoInitialize: true,
looping: widget.looping,
// Errors can occur for example when trying to play a video
// from a non-existent URL
errorBuilder: (context, errorMessage) {
return Center(
child: Text(
errorMessage,
style: TextStyle(color: Colors.white),
),
);
},
);
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Chewie(
controller: _chewieController,
),
);
}
#override
void dispose() {
print("ChewieListItem dispose");
super.dispose();
// IMPORTANT to dispose of all the used resources
widget.videoPlayerController.dispose();
_chewieController.dispose();
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
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> {
String videoname = "Video/Intro.mp4";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
child:
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
ChewieListItem(
key: UniqueKey(),
videoPlayerController: VideoPlayerController.asset(videoname),
looping: false,
),
Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
height: 100.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
IconButton(
icon: Icon(Icons.people),
onPressed: () {
setState(() {
videoname = "Video/Intro.mp4";
print("$videoname");
});
},
),
IconButton(
icon: Icon(Icons.personal_video),
onPressed: () {
setState(() {
videoname = "Video/Intro1.mp4";
print("$videoname");
});
},
),
],
),
),
])),
);
}
}
setState should work for you
onPressed: () {
setState(() {
videoname="Video/Intro1.mp4";
print("$videoname");
});
},