I have Bottom Navigation Bar with 4 tabs and all are working fine but I have another class call BannerImageItem i want to call tab 2 from there. I tried with Gloabal key but getting null from tab controller please help me I am stuck.
I have Bottom Navigation Bar with 4 tabs and all are working fine but I have another class call BannerImageItem i want to call tab 2 from there. I tried with Gloabal key but getting null from tab controller please help me I am stuck.
const int tabCount = 3;
const int turnsToRotateRight = 1;
const int turnsToRotateLeft = 3;
class MainTabControlDelegate {
int index;
Function(String nameTab) changeTab;
Function(int index) tabAnimateTo;
static MainTabControlDelegate _instance;
static MainTabControlDelegate getInstance() {
return _instance ??= MainTabControlDelegate._();
}
MainTabControlDelegate._();
}
class MainTabs extends StatefulWidget {
MainTabs({Key key}) : super(key: key);
#override
MainTabsState createState() => MainTabsState();
}
class MainTabsState extends State<MainTabs>
with
WidgetsBindingObserver,
SingleTickerProviderStateMixin,
AfterLayoutMixin {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final PageStorageBucket bucket = PageStorageBucket();
final StreamController<String> _controllerRouteWeb =
StreamController<String>.broadcast();
final _auth = FirebaseAuth.instance;
var tabData;
Map saveIndexTab = Map();
FirebaseUser loggedInUser;
bool isAdmin = false;
final List<Widget> _tabView = [];
TabController tabController;
#override
void afterFirstLayout(BuildContext context) {
loadTabBar(context);
}
Widget tabView(Map<String, dynamic> data) {
switch (data['layout']) {
case 'category':
return CategoriesScreen(
key: Key("category"),
layout: data['categoryLayout'],
categories: data['categories'],
images: data['images'],
showChat: data['showChat'],
);
case 'search':
return SearchScreen(key: Key("search"), showChat: data['showChat']);
case 'cart':
return CartScreen(showChat: data['showChat']);
case 'profile':
return UserScreen(
settings: data['settings'],
background: data['background'],
showChat: data['showChat']);
case 'blog':
return HorizontalSliderList(config: data);
case 'wishlist':
return screen.WishList(canPop: false, showChat: data['showChat']);
case 'page':
return WebViewScreen(
title: data['title'], url: data['url'], showChat: data['showChat']);
case 'html':
return StaticSite(data: data['data'], showChat: data['showChat']);
case 'static':
return StaticPage(data: data['data'], showChat: data['showChat']);
case 'postScreen':
return PostScreen(
pageId: data['pageId'],
pageTitle: data['pageTitle'],
isLocatedInTabbar: true,
showChat: data['showChat']);
case 'dynamic':
default:
return HomeScreen();
}
}
void changeTab(String nameTab) {
if (kLayoutWeb) {
_controllerRouteWeb.sink
.add(nameTab.contains("/") ? nameTab : '/$nameTab');
} else {
tabController?.animateTo(saveIndexTab[nameTab] ?? 0);
}
}
void loadTabBar(context) {
tabData = Provider.of<AppModel>(context, listen: false).appConfig['TabBar']
as List;
for (var i = 0; i < tabData.length; i++) {
Map<String, dynamic> _dataOfTab = Map.from(tabData[i]);
saveIndexTab[_dataOfTab['layout']] = i;
_tabView.add(tabView(_dataOfTab));
}
setState(() {
tabController = TabController(length: _tabView.length, vsync: this);
});
if (MainTabControlDelegate.getInstance().index != null) {
tabController.animateTo(MainTabControlDelegate.getInstance().index);
} else {
MainTabControlDelegate.getInstance().index = 0;
}
// Load the Design from FluxBuilder
tabController.addListener(() {
eventBus.fire('tab_${tabController.index}');
if (_tabView[tabController.index] is SearchScreen) {
eventBus.fire(UpdateSearchFilterEvent());
}
MainTabControlDelegate.getInstance().index = tabController.index;
});
}
Future<void> getCurrentUser() async {
try {
//Provider.of<UserModel>(context).getUser();
final user = await _auth.currentUser();
if (user != null) {
setState(() {
loggedInUser = user;
});
}
} catch (e) {
printLog("[tabbar] getCurrentUser error ${e.toString()}");
}
}
bool checkIsAdmin() {
if (loggedInUser.email == adminEmail) {
isAdmin = true;
} else {
isAdmin = false;
}
return isAdmin;
}
#override
void initState() {
if (!kIsWeb) {
getCurrentUser();
}
MainTabControlDelegate.getInstance().changeTab = changeTab;
MainTabControlDelegate.getInstance().tabAnimateTo = (int index) {
tabController?.animateTo(index);
};
super.initState();
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
tabController?.dispose();
_controllerRouteWeb?.close();
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
// went to Background
}
if (state == AppLifecycleState.resumed) {
// came back to Foreground
final appModel = Provider.of<AppModel>(context, listen: false);
if (appModel.deeplink?.isNotEmpty ?? false) {
if (appModel.deeplink['screen'] == 'NotificationScreen') {
appModel.deeplink = null;
Navigator.push(
context,
MaterialPageRoute(builder: (context) => NotificationScreen()),
);
}
}
}
super.didChangeAppLifecycleState(state);
}
#override
Widget build(BuildContext context) {
printLog('[tabbar] ============== tabbar.dart DASHBOARD ==============');
final isDesktop = isDisplayDesktop(context);
Utils.setStatusBarWhiteForeground(false);
kLayoutWeb = (kIsWeb || isDesktop);
if (_tabView.isEmpty) {
return Container(
color: Colors.white,
child: kLoadingWidget(context),
);
}
return renderBody(context);
}
Widget renderBody(BuildContext context) {
final ThemeData theme = Theme.of(context);
if (kLayoutWeb) {
final isDesktop = isDisplayDesktop(context);
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: SafeArea(
// For desktop layout we do not want to have SafeArea at the top and
// bottom to display 100% height content on the accounts view.
top: !isDesktop,
bottom: !isDesktop,
child: Theme(
// This theme effectively removes the default visual touch
// feedback for tapping a tab, which is replaced with a custom
// animation.
data: theme.copyWith(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
child: LayoutWebCustom(
menu: MenuBar(controllerRouteWeb: _controllerRouteWeb),
content: StreamBuilder<String>(
initialData: RouteList.homeScreen,
stream: _controllerRouteWeb.stream,
builder: (context, snapshot) {
return Navigator(
key: Key(snapshot.data),
initialRoute: snapshot.data,
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute(
builder: Routes.getRouteByName(settings.name),
settings: settings,
maintainState: false,
fullscreenDialog: true,
);
},
);
},
),
)),
),
);
} else {
final screenSize = MediaQuery.of(context).size;
return Container(
color: Theme.of(context).backgroundColor,
child: Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
resizeToAvoidBottomPadding: false,
key: _scaffoldKey,
body: WillPopScope(
onWillPop: () async {
if (tabController.index != 0) {
tabController.animateTo(0);
return false;
} else {
return showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(S.of(context).areYouSure),
content: Text(S.of(context).doYouWantToExitApp),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text(S.of(context).no),
),
FlatButton(
onPressed: () => Navigator.of(context).pop(true),
child: Text(S.of(context).yes),
),
],
),
) ??
false;
}
},
child: TabBarView(
controller: tabController,
physics: NeverScrollableScrollPhysics(),
children: _tabView,
),
),
drawer: Drawer(child: MenuBar()),
bottomNavigationBar: SafeArea(
top: false,
child: Container(
width: screenSize.width,
child: FittedBox(
child: Container(
width: screenSize.width /
(2 / (screenSize.height / screenSize.width)),
child: TabBar(
controller: tabController,
tabs: renderTabbar(),
isScrollable: false,
labelColor: Theme.of(context).primaryColor,
indicatorSize: TabBarIndicatorSize.label,
indicatorPadding: EdgeInsets.all(4.0),
indicatorColor: Theme.of(context).primaryColor,
),
),
),
),
),
),
);
}
}
List<Widget> renderTabbar() {
final isTablet = Tools.isTablet(MediaQuery.of(context));
var totalCart = Provider.of<CartModel>(context).totalCartQuantity;
final tabData = Provider.of<AppModel>(context, listen: false)
.appConfig['TabBar'] as List;
List<Widget> list = [];
tabData.forEach((item) {
var icon = !item["icon"].contains('/')
? Icon(
featherIcons[item["icon"]],
color: Theme.of(context).accentColor,
size: 22,
)
: (item["icon"].contains('http')
? Image.network(
item["icon"],
color: Theme.of(context).accentColor,
width: 24,
)
: Image.asset(
item["icon"],
color: Theme.of(context).accentColor,
width: 24,
));
if (item["layout"] == "cart") {
icon = Stack(
children: <Widget>[
Container(
width: 30,
height: 25,
padding: const EdgeInsets.only(right: 6.0, top: 4),
child: icon,
),
if (totalCart > 0)
Positioned(
right: 0,
top: 0,
child: Container(
padding: const EdgeInsets.all(1),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(8),
),
constraints: BoxConstraints(
minWidth: 16,
minHeight: 16,
),
child: Text(
totalCart.toString(),
style: TextStyle(
color: Colors.white,
fontSize: isTablet ? 14 : 12,
),
textAlign: TextAlign.center,
),
),
)
],
);
}
if (item["label"] != null) {
list.add(Tab(icon: icon, text: item["label"]));
} else {
list.add(Tab(icon: icon));
}
});
return list;
}
}
and here is BannerImageItem
/// The Banner type to display the image
class BannerImageItem extends StatefulWidget {
#override
final Key key;
final dynamic config;
final double width;
final double padding;
final BoxFit boxFit;
final double radius;
BannerImageItem({
this.key,
this.config,
this.padding,
this.width,
this.boxFit,
this.radius,
}) : super(key: key);
#override
_BannerImageItemState createState() => _BannerImageItemState();
}
class _BannerImageItemState extends State<BannerImageItem>
with AfterLayoutMixin {
List<Product> _products;
GlobalKey<MainTabsState> _scaffoldKey = GlobalKey<MainTabsState>();
#override
void afterFirstLayout(BuildContext context) {
/// for pre-load the list product
if (widget.config['data'] != null) {
print(widget.config['data']);
_products = widget.config['data'];
}
}
#override
Widget build(BuildContext context) {
double _padding =
Tools.formatDouble(widget.config["padding"] ?? widget.padding ?? 10.0);
double _radius = Tools.formatDouble(widget.config['radius'] ??
(widget.radius != null ? widget.radius : 0.0));
final screenSize = MediaQuery.of(context).size;
final screenWidth =
screenSize.width / (2 / (screenSize.height / screenSize.width));
final itemWidth = widget.width ?? screenWidth;
return GestureDetector(key: _scaffoldKey,
onTap: () { _scaffoldKey.currentState.tabController.animateTo(1);
},
child: Container(
width: itemWidth,
child: Padding(
padding: EdgeInsets.only(left: _padding, right: _padding),
child: ClipRRect(
borderRadius: BorderRadius.circular(_radius),
child: Tools.image(
fit: widget.boxFit ?? BoxFit.fitWidth,
url: widget.config["image"],
),
),
),
),
);
}
}
return GestureDetector(key: _scaffoldKey,
onTap: () { _scaffoldKey.currentState.tabController.animateTo(1);
},
child: Container(
width: itemWidth,
child: Padding(
padding: EdgeInsets.only(left: _padding, right: _padding),
child: ClipRRect(
borderRadius: BorderRadius.circular(_radius),
child: Tools.image(
fit: widget.boxFit ?? BoxFit.fitWidth,
url: widget.config["image"],
),
),
),
),
);
replace with
return GestureDetector(
onTap: () { MainTabControlDelegate.getInstance().tabAnimateTo(1);
},
child: Container(
width: itemWidth,
child: Padding(
padding: EdgeInsets.only(left: _padding, right: _padding),
child: ClipRRect(
borderRadius: BorderRadius.circular(_radius),
child: Tools.image(
fit: widget.boxFit ?? BoxFit.fitWidth,
url: widget.config["image"],
),
),
),
),
);
Related
i am creating a flutter wallpaper app i am facing issues in making a list with some categories. images are not loading and it is showing this error [ : package:flutter/src/_newtwork_image_io.dart': failed assertion : line 25 pos 14 : 'url != null' : is not true. see also https://flutter.dev/docs/testing/errors ]
can any help i in this
here is my code for the app
this is my main.dart :===
// this is my main.dart :
import 'package:flutter/material.dart';
import 'package:wallpaperdex/views/home.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'WallpaperDex',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.white,
),
home: Home(),
);
}
}
this is my home.dart where i am creating my list
import 'package:flutter/material.dart';
import 'package:wallpaperdex/data/data.dart';
import 'package:wallpaperdex/model/categorie_model.dart';
import 'package:wallpaperdex/widgets/widget.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
//
List<CategorieModel> categories = new List();
#override
void initState() {
categories = getCategories();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: BrandName(),
elevation: 0.0,
),
body: Container(
child: Column(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(36),
color: Color(0xfff5f8fd),
),
margin: EdgeInsets.symmetric(horizontal: 24),
padding: EdgeInsets.symmetric(horizontal: 20),
child: Row(
children: <Widget>[
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: "Search", border: InputBorder.none),
),
),
Icon(Icons.search),
],
),
),
SizedBox(
height: 16,
),
Container(
height: 80,
child: ListView.builder(
// padding: ,
itemCount: categories.length,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return CategoriesTile(categories[index].categorieName,
categories[index].imgUrl);
},
),
)
],
),
),
);
}
}
class CategoriesTile extends StatelessWidget {
final String imgUrl, title;
CategoriesTile(this.title, this.imgUrl);
#override
Widget build(BuildContext context) {
return Container(
child: Stack(
children: <Widget>[
Container(
child: Image.network(imgUrl),
),
Container(
child: Text(title),
),
],
),
);
}
}
this is my data.dart:
import 'package:wallpaperdex/model/categorie_model.dart';
List<CategorieModel> getCategories() {
List<CategorieModel> categories = new List();
CategorieModel categorieModel = new CategorieModel();
categorieModel.imgUrl =
"https://images.pexels.com/photos/545008/pexels-photo-545008.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500";
categorieModel.categorieName = "Street Art";
categories.add(categorieModel);
categorieModel = new CategorieModel();
//
categorieModel.imgUrl =
"https://images.pexels.com/photos/704320/pexels-photo-704320.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500";
categorieModel.categorieName = "Wild Life";
categories.add(categorieModel);
categorieModel = new CategorieModel();
//
categorieModel.imgUrl =
"https://images.pexels.com/photos/34950/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&w=500";
categorieModel.categorieName = "Nature";
categories.add(categorieModel);
categorieModel = new CategorieModel();
//
categorieModel.imgUrl =
"https://images.pexels.com/photos/466685/pexels-photo-466685.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500";
categorieModel.categorieName = "City";
categories.add(categorieModel);
categorieModel = new CategorieModel();
//
categorieModel.imgUrl =
"https://images.pexels.com/photos/1434819/pexels-photo-1434819.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260";
categorieModel.categorieName = "Motivation";
categories.add(categorieModel);
categorieModel = new CategorieModel();
//
categorieModel.imgUrl =
"https://images.pexels.com/photos/2116475/pexels-photo-2116475.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500";
categorieModel.categorieName = "Bikes";
categories.add(categorieModel);
categorieModel = new CategorieModel();
//
categorieModel.imgUrl =
"https://images.pexels.com/photos/1149137/pexels-photo-1149137.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500";
categorieModel.categorieName = "Cars";
categories.add(categorieModel);
categorieModel = new CategorieModel();
return categories;
}
this is my widget.dart :
import 'package:flutter/material.dart';
// ignore: non_constant_identifier_names
Widget BrandName() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Wallpaper",
style: TextStyle(color: Colors.black87),
),
Text(
"Dex",
style: TextStyle(color: Colors.blue),
)
],
);
}
this is my category_model.dart
class CategorieModel {
String categorieName;
String imgUrl;
}
this is all , here is screenshot of error
enter image description here
I am developing a foreign language application. I have multiple choice test questions in my application, but after I finish the test, I get this error. I wonder if anyone knows the solution to this error.
EXCEPTION : 'package:flutter/src/widgets/framework.dart': Failed assertion: line 4263 pos 12: '_debugLifecycleState != _ElementLifecycle.defunct': is not true.
MY CODES
class LoadJson extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: DefaultAssetBundle.of(context)
.loadString("lib/quiz/questions.json"),
builder: (context, snapshot) {
List mydata = json.decode(snapshot.data.toString());
if (mydata == null) {
return Center(
child: Text("asldöasid"),
);
} else {
return SorularinOlacagiPage(mydata: mydata);
}
},
),
);
}
}
class SorularinOlacagiPage extends StatefulWidget {
final mydata;
const SorularinOlacagiPage({Key key, this.mydata}) : super(key: key);
#override
_SorularinOlacagiPageState createState() =>
_SorularinOlacagiPageState(mydata: mydata);
}
class _SorularinOlacagiPageState extends State<SorularinOlacagiPage>
with SingleTickerProviderStateMixin {
List<QuestionsModel> _myQuestions = new List<QuestionsModel>();
List mydata;
_SorularinOlacagiPageState({this.mydata});
Color colortoShow = Colors.indigo;
Color right = Colors.green;
Color wrong = Colors.red;
int index = 0;
int i = 1;
int marks = 0;
bool disableAnswer = false;
int j = 1;
int timer = 30;
String showTimer = "30";
var random_array;
Animation animation;
AnimationController animationController;
double beginAnim = 0.0;
double endAnim = 1.0;
Map<String, Color> btnColor = {
"a": Colors.indigoAccent,
"b": Colors.indigoAccent,
"c": Colors.indigoAccent,
"d": Colors.indigoAccent
};
bool cancelTimer = false;
genrandomarray() {
var distinctIds = [];
var rand = new Random();
for (int i = 0;;) {
distinctIds.add(rand.nextInt(20));
random_array = distinctIds.toSet().toList();
if (random_array.length < 20) {
continue;
} else {
break;
}
}
print(random_array);
}
//initstate
#override
void initState() {
// startTimer();
genrandomarray();
super.initState();
_myQuestions = getQuestions();
animationController =
AnimationController(duration: const Duration(seconds: 8), vsync: this);
animation =
Tween(begin: beginAnim, end: endAnim).animate(animationController)
..addListener(() {
setState(() {});
});
startAnim();
animationController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
if (j < 20) {
j++;
resetAnim();
startAnim();
} else {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => TrueFalseSSonucSayfasi(marks: marks)));
}
}
});
}
startAnim() {
animationController.forward();
}
resetAnim() {
animationController.reset();
}
stopAnim() {
animationController.stop();
}
#override
void setState(fn) {
if (mounted) {
super.setState(fn);
}
}
/* void startTimer() async {
const oneSec = Duration(seconds: 1);
Timer.periodic(oneSec, (Timer t) {
setState(() {
if (timer < 1) {
t.cancel();
nextQuestion();
} else if (cancelTimer == true) {
t.cancel();
} else {
timer = timer - 1;
}
showTimer = timer.toString();
});
});
}*/
void nextQuestion() {
if (j < 20) {
i = random_array[j];
j++;
resetAnim();
startAnim();
} else {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => TrueFalseSSonucSayfasi(
marks: marks,
)));
}
btnColor["a"] = Colors.indigoAccent;
btnColor["b"] = Colors.indigoAccent;
btnColor["c"] = Colors.indigoAccent;
btnColor["d"] = Colors.indigoAccent;
disableAnswer = false;
}
void checkAnswer(String k) {
//Sorular -0 şıklar-1 cevaplar -1 =>index numarları
if (mydata[2][i.toString()] == mydata[1][i.toString()][k]) {
//answer is correct
marks = marks + 5;
colortoShow = right;
} else {
//answer is wrong
colortoShow = wrong;
}
setState(() {
cancelTimer = true;
btnColor[k] = colortoShow;
disableAnswer = true;
});
Timer(Duration(seconds: 2), nextQuestion);
}
Widget choiceButton(String k) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: MaterialButton(
onPressed: () => checkAnswer(k),
child: Text(
mydata[1][i.toString()][k],
style: TextStyle(color: Colors.white, fontSize: 16),
maxLines: 1,
),
//color: btnColor[k],
color: btnColor[k],
splashColor: Colors.indigo.shade700,
highlightColor: Colors.indigo.shade700,
minWidth: 200,
height: 45,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
),
);
}
#override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitDown, DeviceOrientation.portraitUp]);
return WillPopScope(
child: Scaffold(
body: Column(
children: [
Container(
padding: EdgeInsets.only(left: 30, right: 30, top: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"${j} / ${_myQuestions.length}",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.w500),
),
Text(
getTranslated(context, "ssoru"),
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w400),
),
Spacer(),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"$marks",
style: TextStyle(
fontSize: 24, fontWeight: FontWeight.w500),
),
SizedBox(
height: 10,
),
Text(
getTranslated(context, "puan"),
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.w400),
),
],
),
],
),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.all(15),
alignment: Alignment.bottomLeft,
child: Container(
child: LinearProgressIndicator(
value: animation.value,
),
),
),
),
Expanded(
flex: 3,
child: Image.asset(
mydata[0][i.toString()],
),
),
Expanded(
flex: 6,
child: AbsorbPointer(
absorbing: disableAnswer,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
choiceButton("a"),
choiceButton("b"),
choiceButton("c"),
choiceButton("d"),
],
),
),
),
),
],
),
),
onWillPop: () {
return showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text("Test"),
content: Text("Bu Aşamada Geri Dönemezsin"),
actions: [
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("Tamam"),
),
],
));
},
);
}
}
EXCEPTION
════════ Exception caught by animation library ═════════════════════════════════════════════════════
The following assertion was thrown while notifying listeners for AnimationController:
'package:flutter/src/widgets/framework.dart': Failed assertion: line 4263 pos 12: '_debugLifecycleState != _ElementLifecycle.defunct': is not true.
You must dispose your animationController in the void dispose() function like this.
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
and make sure to call super.dispose() afterwards
I'm a beginner in coding, and I'm having issues with my program. it was working just fine yesterday. The image is not being shown from the API and the yellow stripes... I tried using 'flexible' to try and fix but unsuccessful. if anyone can just look at this for me and show me what am missing, I would be really grateful.
'''
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primaryColor: Colors.deepPurple),
home: MyHomePage(title: 'Book Search'),
);
}
}
class BookListItem extends StatefulWidget {
const BookListItem({
this.thumbnail,
this.title,
this.releaseDate,
this.author,
});
final Widget thumbnail;
final String title;
final String releaseDate;
final String author;
#override
_BookListItemState createState() => _BookListItemState();
}
class _BookListItemState extends State<BookListItem> {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 18.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 2,
child: widget.thumbnail,
),
const Icon(
Icons.more_vert,
size: 16.0,
),
],
),
);
}
}
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 search = "a";
String userSearch = "";
String aURL = "https://www.googleapis.com/books/v1/volumes?q=";
final myController = TextEditingController();
TextEditingController controller = new TextEditingController();
Object get jsonData => null;
filtersearch(String text) {
setState(() {
if (text != "") {
this.search = text;
}
});
}
validate(data, opdata) {
if (data == null) {
return opdata;
}
return data;
}
//fetch data from api
Future<List<Book>> _getUsers() async {
//use this site to generate json data
print(this.search + " search");
var url = "https://www.googleapis.com/books/v1/volumes?q=" + this.search;
var data = await http.get(url);
//convert response to json Object
var jsonData = json.decode(data.body);
//Store data in User list from JsonData
List<Book> books = [];
for (var item in jsonData["items"]) {
Book book = new Book(
item["volumeInfo"]["title"],
item["volumeInfo"]["subtitle"],
item["volumeInfo"]["imageLinks"]["thumbnail"],
item["volumeInfo"]["authors"][0],
item["volumeInfo"]["publishedDate"]);
//add data to object
books.add(book);
}
//return user list
return books;
}
Icon seaicon = Icon(Icons.search);
Widget seabar = Text(
"My Book Search Bar",
);
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
leading: IconButton(icon: Icon(Icons.menu), onPressed: () {}),
centerTitle: true,
title: seabar,
actions: <Widget>[
IconButton(
icon: seaicon,
onPressed: () {
setState(() {
if (this.seaicon.icon == Icons.search) {
this.seaicon = Icon(Icons.cancel);
this.seabar = TextField(
controller: controller,
textInputAction: TextInputAction.go,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Search",
),
onSubmitted: (String userInput) {
setState(() {
print(userInput);
if (userInput != "") {
this.search = userInput;
} else {
this.search = "a";
}
});
},
);
} else {
this.seaicon = Icon(Icons.search);
this.seabar = Text("AppBar");
}
});
})
]),
body: Center(
child: Container(
child: FutureBuilder(
future: _getUsers(),
// ignore: missing_return
builder: (BuildContext context, AsyncSnapshot snapshot) {
print(snapshot.data);
if (snapshot.hasData) {
return ListView.builder(
itemExtent: 90.0,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return new Card(
child: new Container(
padding: EdgeInsets.all(8.0),
child: new Row(
children: [
new CircleAvatar(
child:
Image.network(snapshot.data[index].thumbnail),
maxRadius: 50,
),
new Padding(padding: EdgeInsets.only(right: 10.0)),
new Text(
snapshot.data[index].title +
"\n" +
snapshot.data[index].author +
"\n" +
snapshot.data[index].publishedDate,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 18.0),
maxLines: 3,
),
],
),
),
);
},
);
} else if (snapshot.data == null &&
snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Container(
width: 160,
height: 150,
child: Column(
children: <Widget>[
SizedBox(
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(
Colors.purple),
),
width: 70,
height: 70,
),
const Padding(
padding: EdgeInsets.only(top: 20),
child: Text(
'Loading Book List...',
style: TextStyle(color: Colors.black),
),
)
],
)),
);
} else if (snapshot.data == null &&
snapshot.connectionState == ConnectionState.none) {
return Center(
child: Container(
width: 100,
height: 90,
child: Column(
children: <Widget>[
Padding(
padding: null,
child: Text(
'no result founds',
style: TextStyle(color: Colors.black),
),
),
],
)),
);
} else if (snapshot.data == null) {
return Text(
'no result founds',
style: TextStyle(color: Colors.black),
);
}
},
),
),
),
);
}
}
// on tap to show details
class BookDetails extends StatelessWidget {
final Book book;
BookDetails(this.book);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Book Search"),
),
body: Container(
child: Card(
child: Column(
children: [
Text("Title: " + book.title),
Text("Subtitle: " + book.subtitle),
Text("Thumbnail: " + book.thumbnail),
Text("Author: " + book.author),
Text("Published Date: " + book.publishedDate),
],
),
),
),
);
}
}
//Book Class
class Book {
final String title;
final String subtitle;
final String thumbnail;
final String author;
final String publishedDate;
//Constructor to intitilize
Book(this.title, this.subtitle, this.thumbnail, this.author,
this.publishedDate);
static void add(Book book) {}
}
'''
You can copy paste run full code below
Step 1: You need to add android:usesCleartextTraffic="true" in AndroidManifest.xml , because json for image link use http
<application
android:name="io.flutter.app.FlutterApplication"
android:usesCleartextTraffic="true"
android:label="so_issue557"
android:icon="#mipmap/ic_launcher">
Your json result for image
"imageLinks": {
"smallThumbnail": "http://books.google.com/books/content?id=o19zBQAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
"thumbnail": "http://books.google.com/books/content?id=o19zBQAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
},
Step 2: Wrap Text with Expanded
Expanded(
child: Text(
snapshot.data[index].title +
"\n" +
snapshot.data[index].author +
"\n" +
snapshot.data[index].publishedDate,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 18.0),
maxLines: 3,
),
),
working demo
full code
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primaryColor: Colors.deepPurple),
home: MyHomePage(title: 'Book Search'),
);
}
}
class BookListItem extends StatefulWidget {
const BookListItem({
this.thumbnail,
this.title,
this.releaseDate,
this.author,
});
final Widget thumbnail;
final String title;
final String releaseDate;
final String author;
#override
_BookListItemState createState() => _BookListItemState();
}
class _BookListItemState extends State<BookListItem> {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 18.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 2,
child: widget.thumbnail,
),
const Icon(
Icons.more_vert,
size: 16.0,
),
],
),
);
}
}
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 search = "a";
String userSearch = "";
String aURL = "https://www.googleapis.com/books/v1/volumes?q=";
final myController = TextEditingController();
TextEditingController controller = TextEditingController();
Object get jsonData => null;
filtersearch(String text) {
setState(() {
if (text != "") {
this.search = text;
}
});
}
validate(data, opdata) {
if (data == null) {
return opdata;
}
return data;
}
//fetch data from api
Future<List<Book>> _getUsers() async {
//use this site to generate json data
print(this.search + " search");
var url = "https://www.googleapis.com/books/v1/volumes?q=" + this.search;
var data = await http.get(url);
//convert response to json Object
var jsonData = json.decode(data.body);
//Store data in User list from JsonData
List<Book> books = [];
for (var item in jsonData["items"]) {
Book book = Book(
item["volumeInfo"]["title"],
item["volumeInfo"]["subtitle"],
item["volumeInfo"]["imageLinks"]["thumbnail"],
item["volumeInfo"]["authors"][0],
item["volumeInfo"]["publishedDate"]);
//add data to object
books.add(book);
}
//return user list
return books;
}
Icon seaicon = Icon(Icons.search);
Widget seabar = Text(
"My Book Search Bar",
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(icon: Icon(Icons.menu), onPressed: () {}),
centerTitle: true,
title: seabar,
actions: <Widget>[
IconButton(
icon: seaicon,
onPressed: () {
setState(() {
if (this.seaicon.icon == Icons.search) {
this.seaicon = Icon(Icons.cancel);
this.seabar = TextField(
controller: controller,
textInputAction: TextInputAction.go,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Search",
),
onSubmitted: (String userInput) {
setState(() {
print(userInput);
if (userInput != "") {
this.search = userInput;
} else {
this.search = "a";
}
});
},
);
} else {
this.seaicon = Icon(Icons.search);
this.seabar = Text("AppBar");
}
});
})
]),
body: Center(
child: Container(
child: FutureBuilder(
future: _getUsers(),
// ignore: missing_return
builder: (BuildContext context, AsyncSnapshot snapshot) {
print(snapshot.data);
if (snapshot.hasData) {
return ListView.builder(
itemExtent: 90.0,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Card(
child: Container(
padding: EdgeInsets.all(8.0),
child: Row(
children: [
CircleAvatar(
child:
Image.network(snapshot.data[index].thumbnail),
maxRadius: 50,
),
Padding(padding: EdgeInsets.only(right: 10.0)),
Expanded(
child: Text(
snapshot.data[index].title +
"\n" +
snapshot.data[index].author +
"\n" +
snapshot.data[index].publishedDate,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 18.0),
maxLines: 3,
),
),
],
),
),
);
},
);
} else if (snapshot.data == null &&
snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Container(
width: 160,
height: 150,
child: Column(
children: <Widget>[
SizedBox(
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(Colors.purple),
),
width: 70,
height: 70,
),
const Padding(
padding: EdgeInsets.only(top: 20),
child: Text(
'Loading Book List...',
style: TextStyle(color: Colors.black),
),
)
],
)),
);
} else if (snapshot.data == null &&
snapshot.connectionState == ConnectionState.none) {
return Center(
child: Container(
width: 100,
height: 90,
child: Column(
children: <Widget>[
Padding(
padding: null,
child: Text(
'no result founds',
style: TextStyle(color: Colors.black),
),
),
],
)),
);
} else if (snapshot.data == null) {
return Text(
'no result founds',
style: TextStyle(color: Colors.black),
);
}
},
),
),
),
);
}
}
// on tap to show details
class BookDetails extends StatelessWidget {
final Book book;
BookDetails(this.book);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Book Search"),
),
body: Container(
child: Card(
child: Column(
children: [
Text("Title: " + book.title),
Text("Subtitle: " + book.subtitle),
Text("Thumbnail: " + book.thumbnail),
Text("Author: " + book.author),
Text("Published Date: " + book.publishedDate),
],
),
),
),
);
}
}
//Book Class
class Book {
final String title;
final String subtitle;
final String thumbnail;
final String author;
final String publishedDate;
//Constructor to intitilize
Book(this.title, this.subtitle, this.thumbnail, this.author,
this.publishedDate);
static void add(Book book) {}
}
I will want to know how to change the text indicative of the number of selected element on a Datatable.
Hi, I would like to know how to change the text indicating the number of elements selected on a Datatable.
Instead of this "1 item selected" I would like to have this "1 delivery selected".
My DataTableSource code :
class DeliveryTableSource extends DataTableSource {
List<RequestDeliverySource> _list;
int _rowSelectedCount = 0;
DeliveryTableSource(this._list);
#override
DataRow getRow(int index) {
if (index < 0 || index > _list.length)
return null;
else {
RequestDeliverySource source = _list[index];
return DataRow.byIndex(
cells: buildCells(source),
index: index,
selected: source.isSelected,
onSelectChanged: (bool value) {
if (source.isSelected != value) {
_rowSelectedCount += value ? 1 : -1;
source.isSelected = value;
notifyListeners();
}
});
}
}
List<DataCell> buildCells(RequestDeliverySource source) {
return [
DataCell(Text("${source.name}")),
DataCell(Text("${source.deliveryAddress}")),
DataCell(Text("${source.pickupAddress}")),
DataCell(Text("${source.plannedDeliveryDate}")),
DataCell(Text("${source.effectiveDeliveryDate}")),
DataCell(Text("${source.showStatus()}"))
];
}
void selectedAll(bool checked) {
_list.forEach((source) {
source.isSelected = checked;
});
_rowSelectedCount = checked ? _list.length : 0;
notifyListeners();
}
#override
bool get isRowCountApproximate => false;
#override
int get rowCount => _list.length;
#override
int get selectedRowCount => _rowSelectedCount;
}
My component widget Table :
class DeliveryTable extends StatefulWidget {
DeliveryTable({Key key}) : super(key: key);
#override
State<StatefulWidget> createState() {
return new DeliveryTableState();
}
}
class DeliveryTableState extends State<DeliveryTable> {
int _rowsPerPage = 10;
#override
Widget build(BuildContext context) {
RequestDelivery delivery = new RequestDelivery();
delivery.name = "livraison test";
RequestDeliverySource source = new RequestDeliverySource(delivery);
DeliveryTableSource tableSource = new DeliveryTableSource([source]);
return Container(
width: double.infinity,
child: SingleChildScrollView(
child: PaginatedDataTable(
header: Text("Livraison effectuée",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16.0)),
rowsPerPage: _rowsPerPage,
onSelectAll: tableSource.selectedAll,
onRowsPerPageChanged: (int value) {
setState(() {
_rowsPerPage = value;
});
},
columns: _buildColumns(),
source: tableSource)));
}
List<DataColumn> _buildColumns() {
return [
DataColumn(label: Text("Nom"), tooltip: "Nom de la livraison"),
DataColumn(
label: Text("Lieux de livraison"), tooltip: "Adresse de livraison"),
DataColumn(
label: Text("Lieux de ramassage"), tooltip: "Adresse de ramassage"),
DataColumn(
label: Text("Date de livraison"), tooltip: "Date de livraison"),
DataColumn(
label: Text("Livrée le"), tooltip: "Date de livraison effective"),
DataColumn(label: Text("Statut"), tooltip: "Statu de la livraison")
];
}
}
That happens because the PaginatedDataTable will replace the header if the count is bigger than 0 from the source provided. To bypass this, you can create your own header and your own getter in your DataTableSource.
class DataTable extends StatefulWidget {
_DataTableState createState() => _DataTableState();
}
class _DataTableState extends State<DataTable> {
final source = MySource();
#override
Widget build(BuildContext context) {
return PaginatedDataTable(
columns: <DataColumn>[
DataColumn(
label: Text('Label'),
),
],
header: Container(
child: Text('I have ${source.selectedItems} deliveries selected.'),
),
source: source,
);
}
}
class MySource extends DataTableSource {
#override
DataRow getRow(int index) {
return DataRow(
cells: <DataCell>[
DataCell(
Text('New cell'),
),
],
);
}
int get selectedItems => 20; // Create your own counter
#override
bool get isRowCountApproximate => false;
#override
int get rowCount => 10;
#override
int get selectedRowCount => 0; // You want to keep this at zero
}
How to make a function in Flutter which will Read audio files from SD card and display them to a ListView?
If you're asking about showing list of audio-files - here example of my code:
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_app/storage.dart';
import 'package:path_provider/path_provider.dart';
import 'package:simple_permissions/simple_permissions.dart';
class BrowserScaffold extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _BrowserScaffoldState();
}
}
class _BrowserScaffoldState extends State<BrowserScaffold> {
final List<FileSystemEntity> files = List<FileSystemEntity>();
final savedFiles = Set<File>();
Directory parent;
ScrollController controller = ScrollController();
#override
Widget build(BuildContext context) {
if (parent == null) {
SimplePermissions
.requestPermission(Permission.WriteExternalStorage)
.then((value) {
if (value == PermissionStatus.authorized) {
localPath.then((String value) {
Directory dir = Directory(value);
while (dir.path != dir.parent.path) {
dir.isAbsolute;
dir = dir.parent;
}
parent = dir;
setState(() {
files.addAll(dir.parent.listSync());
sortFiles();
});
});
} else {
SimplePermissions.openSettings();
}
});
}
return Scaffold(
appBar: AppBar(
title: Text('Files'),
actions: <Widget>[
IconButton(icon: Icon(Icons.check), onPressed: apply),
],
),
body: buildList(),
);
}
void sortFiles() {
for (int i = files.length - 1; i >= 0; i--) {
FileSystemEntity entity = files[i];
if (entity is Link) {
files.remove(entity);
} else if (entity is Directory) {
try {
entity.listSync();
} catch (ex) {
print('catch: ${entity.path}, $ex');
files.remove(entity);
}
}
}
files.sort((FileSystemEntity a, FileSystemEntity b) {
if (a is Directory && b is File) return -1;
if (a is File && b is Directory) return 1;
return a.path.compareTo(b.path);
});
}
Widget buildList() {
if (parent == null) return ListView();
bool isRoot = parent.path == parent.parent.path;
return ListView.builder(
itemBuilder: (context, i) {
if (i.isOdd)
return Divider(
height: 4.0,
);
final index = isRoot ? i ~/ 2 : i ~/ 2 - 1;
return buildRow(index);
},
itemCount: isRoot ? files.length * 2 : (files.length + 1) * 2,
controller: controller,
);
}
Widget buildRow(int index) {
if (index == -1) return getRootTile();
FileSystemEntity file = files[index];
if (file is Directory) return getDirectoryTile(file);
if (file is File) return getFileTile(file);
if (file is Link)
return Container(
height: 0.0,
);
return Container(
height: 0.0,
);
}
Widget getRootTile() {
return ListTile(
title: Text('../'),
trailing: Icon(Icons.keyboard_backspace),
onTap: () {
setState(() {
parent = parent.parent;
List<FileSystemEntity> rootList = parent.listSync();
files.clear();
files.addAll(rootList);
sortFiles();
});
},
);
}
Widget getDirectoryTile(Directory dir) {
return ListTile(
title: Text(dir.path.split('/').last),
trailing: Icon(
Icons.folder_open,
color: Colors.grey,
),
onTap: () {
setState(() {
parent = dir;
files.clear();
files.addAll(dir.listSync());
sortFiles();
});
},
);
}
Widget getFileTile(File file) {
bool isSaved = savedFiles.map((file) => file.path).contains(file.path);
final List<String> extensions = <String>[
"MP3",
"WAV",
"AAC",
"WMA",
"AMR",
"OGG",
"MIDI"
];
bool isRightType =
extensions.contains(file.path.split('.').last.toUpperCase());
return ListTile(
title: Text(file.path.split('/').last),
trailing: isRightType
// ignore: missing_required_param
? IconButton(
icon: Icon(
isSaved ? Icons.check_box : Icons.check_box_outline_blank,
color: isSaved ? Colors.blueGrey : Colors.grey,
),
)
: null,
onTap: () {
setState(() {
if (isSaved) {
savedFiles.remove(file);
} else {
savedFiles.add(file);
}
});
},
);
}
void apply() async {
final List<Track> list = List();
list.addAll(savedFiles.map((file) => Track(file.path)));
Navigator.of(context).pop(list);
}
Future<String> get localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
}
In my case I show all files, but only audio is selectable (with checkbox)
if you're talking about being able to identify a file extension, then you first need to install Path and import it:
import 'package:path/path.dart' as p;
then check against this:
String _extension = p.extension(_someFile).split('?').first;
I suggest you read the documentation of Android Studio | Files
You can use fileList() to get an ArrayList
Further, use a for loop to get the names and paths -> file.getName() | file.getPath()