Sunmi V2 with Flutter - android

How can I use Flutter to print in Sunmi V2?
I am trying to use this package: https://pub.dev/packages/sunmi
But there is no clear explanation of how to use it

There is a new flutter plugin for Sunmi printers: flutter_sunmi_printer
It can print texts with styles (bold, underline, align, font size), tables (using Bootstrap-like grid system), images etc.
import 'package:flutter_sunmi_printer/flutter_sunmi_printer.dart';
// Text with styles
SunmiPrinter.text('left');
SunmiPrinter.text(
'center',
styles: SunmiStyles(bold: true, underline: true, align: SunmiAlign.center),
);
SunmiPrinter.text(
'right',
styles: SunmiStyles(bold: true, underline: true, align: SunmiAlign.right),
);
// Table
SunmiPrinter.row(
cols: [
SunmiCol(text: 'col1', width: 4),
SunmiCol(text: 'col2', width: 4, align: SunmiAlign.center),
SunmiCol(text: 'col3', width: 4, align: SunmiAlign.right),
],
);
// Image
ByteData bytes = await rootBundle.load('assets/rabbit_black.jpg');
final buffer = bytes.buffer;
final imgData = base64.encode(Uint8List.view(buffer));
SunmiPrinter.image(imgData);

You can see github https://github.com/irpankusuma/SUNMI_AIDL_PRINTER
Full example code https://github.com/irpankusuma/SUNMI_AIDL_PRINTER/tree/master/example
In pubspec.yaml manually add
assets:
- assets/images/
from widget/config.dart add the following png and jpg to assets/images
const String defaultLogoImage = "assets/images/logo.png";
const String defaultPrintLogoImage = "assets/images/print-logo.png";
const String defaultErrorImage = "assets/images/error_404.jpg";
Print Page
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:sunmi_aidl_print_example/blocs/blocs.dart';
import 'package:sunmi_aidl_print_example/blocs/printing_bloc.dart';
import 'package:sunmi_aidl_print_example/config.dart' as config;
import 'package:flutter/material.dart';
import 'package:sunmi_aidl_print/models.dart';
import 'package:sunmi_aidl_print/sunmi_aidl_print.dart';
import 'package:sunmi_aidl_print_example/models/models.dart';
import 'package:sunmi_aidl_print_example/common/common.dart';
class PrintingPage extends StatefulWidget {
#override
State<PrintingPage> createState() => PrintingPageState();
}
class PrintingPageState extends State<PrintingPage>{
List<SunmiPrinter> array = <SunmiPrinter>[];
List<MenuService> menus = <MenuService>[];
Uint8List bytes;
#override
void initState() {
super.initState();
_getBytesImage();
SunmiAidlPrint.bindPrinter();
}
#override
void dispose() {
super.dispose();
SunmiAidlPrint.unbindPrinter();
}
void _getBytesImage() async{
ByteData getBytes = await rootBundle.load(config.defaultPrintLogoImage);
Uint8List image = getBytes.buffer.asUint8List();
setState(() => bytes = image);
}
void _generateMenu() {
menus.add(new MenuService(
name:'TEXT',
icons: Icon(Icons.text_fields),
onTap: () => null
));
}
void _openAlert({ String error}){
showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Alert'),
content: new Text(error),
)
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('PRINT EXAMPLE'),
),
body: new Container(
child: BlocListener<PrintingBloc,PrintingState>(
listener: (context,state){
if(state is ErrorPrinting){ _openAlert(error:state.error); }
},
child: BlocBuilder<PrintingBloc,PrintingState>(
builder: (context,state){
if(state is LoadingPrinting){ return new LoadingIndicator(); }
if(state is InitialPrinting){
return new Container(
child: new MenuServiceState(items:menus,),
);
}
if(state is LoadedPrinting){
return new Container(
child: new MenuServiceState(items:menus,),
);
}
new Container();
},
),
),
),
);
}
}
class MenuServiceState extends StatelessWidget {
final List<MenuService> items;
final int crossAxis;
MenuServiceState({ this.items, this.crossAxis=3 });
#override
Widget build(BuildContext context) {
return new Container(
margin: EdgeInsets.only(top:8.0,bottom:8.0),
child: new GridView.builder(
shrinkWrap: true,
gridDelegate:new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:crossAxis),
physics: ClampingScrollPhysics(),
itemCount: items.length,
itemBuilder: (context,i) => new GestureDetector(
onTap: () => items[i].onTap,
child: new Container(
alignment: Alignment.center,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Container(
decoration: new BoxDecoration(
border: Border.all(color:Colors.grey,width:1.0),
borderRadius: new BorderRadius.all(new Radius.circular(20.0))
),
padding: EdgeInsets.all(12.0),
child: items[i].icons,
),
new Padding(padding: EdgeInsets.only(top:6.0),),new Text("${items[i].name}")
],
),
),
),
),
);
}
}

Related

UI does not get updated when using `Notifier`

I basically have a four-page sample app that I'm just getting started with, and I developed a custom bottom navigation bar. However, when I switch pages (using PageView and Riverpod) or tap on the BlurBottomNav buttons, it changes pages but the BlurBottomNav UI doesn't get updated. I am using flutter_riverpod: ^2.1.1
What I have tried-
I have tried to convert NavButton from stateless to consumer and get ref.watch there
I have tried StateNotifier instead of Notifier
Update: Same Code works when using ChangeNotifier with ChangeNotifierProvider but it doesn't with Notifier
Here are snippets
pageview_widget.dart
import 'package:demo/src/constants/nav_items.dart';
import 'package:demo/src/features/categories/presentation/categories_page.dart';
import 'package:demo/src/features/favourites/presentation/fav_page.dart';
import 'package:demo/src/features/pageview/data/pageview_service.dart';
import 'package:demo/src/features/pageview/presentation/bottom_nav/bottom_nav.dart';
import 'package:demo/src/features/settings/presentation/settings_page.dart';
import 'package:demo/src/features/wallpaper/presentation/wall_list.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class PageViewWidget extends StatefulWidget {
const PageViewWidget({super.key});
#override
State<PageViewWidget> createState() => _PageViewWidgetState();
}
class _PageViewWidgetState extends State<PageViewWidget> {
final pageController = PageController(initialPage: 0);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Breezy'),
),
body: Consumer(
builder: (context, ref, child) {
final pageviewService = ref.watch(pageviewServiceProvider.notifier);
final pageviewServiceRead = ref.watch(pageviewServiceProvider);
return Stack(
children: [
PageView.builder(
itemCount: 4,
controller: pageController,
onPageChanged: (int index) {
pageviewService.onPageChanged(index);
// pageviewService.changeShowBNB(true);
},
itemBuilder: (context, index) {
switch (index) {
case 0:
return const WallpaperList();
case 1:
return const CategoriesPage();
case 2:
return const FavouritesPage();
case 3:
return const SettingsPage();
default:
// Should never get hit.
return CircularProgressIndicator(
color: Theme.of(context).primaryColor,
);
}
}),
Positioned.fill(
bottom: 20,
child: SafeArea(
child: BlurBottomNav(
onItemSelected: (int value) {
pageviewService.onTapByBnb(value, pageController);
},
selectedIndex: pageviewServiceRead.currentindex,
items: navItems,
),
),
),
],
);
},
));
}
}
here is pageview_service.dart
import 'package:demo/src/features/pageview/domain/pageview_navigation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class PageViewService extends Notifier<PageViewNavigation> {
#override
PageViewNavigation build() {
return PageViewNavigation(
currentindex: 0, changedByBNB: false, showBNB: true);
}
void changeShowBNB(bool value) {
state.showBNB = value;
}
void changeIndex(int index) {
state.currentindex = index;
}
void _changeBNBBool(bool value) {
state.changedByBNB = value;
}
void onPageChanged(int index) {
if ((index != state.currentindex) && (!state.changedByBNB)) {
changeIndex(index);
} else {
_changeBNBBool(false);
}
}
void onTapByBnb(int index, PageController pageController) {
if (index != state.currentindex) {
if (pageController.hasClients) {
_changeBNBBool(true);
changeIndex(index);
pageController.animateToPage(
index,
curve: Curves.fastOutSlowIn,
duration: const Duration(milliseconds: 350),
);
}
}
}
}
final pageviewServiceProvider =
NotifierProvider<PageViewService, PageViewNavigation>(PageViewService.new);
here is bottom_nav.dart
import 'dart:ui';
import 'package:demo/src/features/pageview/domain/nav_button.dart';
import 'package:demo/src/features/pageview/presentation/bottom_nav/nav_buttons.dart';
import 'package:flutter/material.dart';
class BlurBottomNav extends StatelessWidget {
final List<BottomNavBarItem> items;
final ValueChanged<int> onItemSelected;
final int selectedIndex;
const BlurBottomNav({
super.key,
required this.items,
required this.onItemSelected,
required this.selectedIndex,
});
#override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.65,
height: 57,
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Container(
height: 100,
color: Colors.red,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: items.map((item) {
var index = items.indexOf(item);
return GestureDetector(
onTap: () => onItemSelected(index),
child: NavButton(
item: item,
isSelected: index == selectedIndex,
),
);
}).toList(),
),
),
),
),
),
),
);
}
}
here is bottom_nav_button.dart
import 'dart:ui';
import 'package:demo/src/features/pageview/domain/nav_button.dart';
import 'package:flutter/material.dart';
class NavButton extends StatelessWidget {
final BottomNavBarItem item;
final bool isSelected;
const NavButton({
super.key,
required this.item,
required this.isSelected,
});
#override
Widget build(BuildContext context) {
return Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
height: 100,
width: 43,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: Colors.purple,
width: 2,
),
color: isSelected ? item.activeIconColor : Colors.white,
),
child: item.icon,
),
),
),
],
);
}
}
and lastly here is BottomNavBarItem
import 'package:flutter/material.dart';
class BottomNavBarItem {
BottomNavBarItem({
required this.icon,
required this.activeIconColor,
});
final Widget icon;
final Color activeIconColor;
}
I haven't used flutter in a while, so please be gentle with me
Keep in mind that you can't use mutable state like this in your Notifier subclasses:
state.showBNB = value;
Instead it should be:
state = /* new state */
If you have a custom state class, make sure all properties are final and add a copyWith method.

Change API JSON call Link whenever i click the next tab for flutter river pods

I am using flutter river pods for this project. I want to change the API call when pressing on the second and third tab. I.e make the JSON API link dynamic. How can I do that?
Each widget is in its different file
Here is my code
main.dart
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: true,
home: HomeView(),
);
}
}
Home_views.dart
class HomeView extends ConsumerWidget {
const HomeView({Key? key}) : super(key: key);
#override
Widget build(BuildContext context, WidgetRef ref) {
TabController controller;
final ModelView = ref.watch(getFutureData);
return Consumer(
builder: (context, WidgetRef ref, _) {
return TabBarWidget;
}
);
}
}
Data_model.dart
class DataModel {
const DataModel({
required this.id,
required this.joke,
required this.categories,
});
final int id;
final String joke;
final String categories;
}
data_controllers.dart
final getFutureData = ChangeNotifierProvider<GetApiDATA>((ref) => GetApiDATA());
class GetApiDATA extends ChangeNotifier{
List<DataModel> ListOfDataModels = [];
GetApiDATA(){
getDataApi();
}
Future getDataApi() async {
ListOfDataModels = [];
try{
http.Response ApiResponse = await http.get(Uri.parse("https://v2.jokeapi.dev/joke/Programming?type=single&contains=joke&amount=10"));
if (ApiResponse.statusCode == 200) {
final body = jsonDecode(ApiResponse.body) as Map<String, dynamic>;
if (body['error'] == false) {
final jokes = body['jokes'];
for (final joke in jokes) {
final jokeMap = joke as Map<String, dynamic>;
print("jokeText is ${jokeMap['joke']}");
final id = jokeMap['id'] as int;
final jokeText = jokeMap['joke'] as String;
final categories = jokeMap['category'] as String;
ListOfDataModels.add(DataModel(id: id, joke: jokeText, categories: categories));
}
print("Length is ${ListOfDataModels.length}");
notifyListeners();
}
}
}
catch(e)
{
print(e.toString());
}
}
}
TabBarWidget.dart
import 'package:assignment_moe/Controllers/data_controllers.dart';
import 'package:assignment_moe/Widgets/TabViewWidget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
Widget TabBarWidget = Consumer(
builder: (context, WidgetRef ref, _) {
final ModelView = ref.watch(getFutureData);
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
backgroundColor: Color(0XffF7F7F7),
appBar: AppBar(
backgroundColor: Color(0xff1B9C8F),
title: Text('Jokes API'),
),
body: Column(
children: [
Container(
margin: const EdgeInsets.only(top: 30, left: 10,right: 10),
height: 35,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
),
child: TabBar(
indicator: BoxDecoration(
color: Color(0xff1B9C8F),
borderRadius: BorderRadius.all(Radius.circular(10)),
),
labelColor: Colors.white,
unselectedLabelColor: Color(0xff1B9C8F),
tabs: [
Tab(
text: 'Programming',
),
Tab(
text: 'Dark',
),
Tab(
text: 'Spooky',
),
],
),
),
Expanded(
child: TabBarView(
children: [
TabViewWidget,
TabViewWidget,
TabViewWidget,
],
),
),
],
),
),
),
);
}
);
TabViewWidget.dart
import 'package:assignment_moe/Controllers/data_controllers.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
Widget TabViewWidget = Consumer (
builder: (context, WidgetRef ref, _) {
final ModelView = ref.watch(getFutureData);
return ModelView.ListOfDataModels.isEmpty ?
Center(child: CircularProgressIndicator(),) :
ListView.builder(
itemCount: ModelView.ListOfDataModels.length,
itemBuilder: (context, index) =>
Container(
margin: EdgeInsets.only(top: 20,left: 20,right: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListTile(
title: Text(ModelView.ListOfDataModels[index].categories
),
subtitle: Padding(
padding: const EdgeInsets.only(top: 10),
child: Text(ModelView.ListOfDataModels[index].joke),
),
leading: Container(
alignment: Alignment.center,
width: 35,
height: 35,
decoration: BoxDecoration(
color: Color(0xff1B9C8F),
borderRadius: BorderRadius.circular(20)),
child: Text(
ModelView.ListOfDataModels[index].id.toString(),
style: TextStyle(color: Colors.white),
),
),
),
),
),
);
}
);
Below is the screen shot
ANy help would be appreciated

How to display image from phones gallery?

I'm trying to display a image on an android phone from the phones photo gallery using flutter and the /image_picker import but I keep on running into this problem:
'A value of type 'XFile?' can't be assigned to a variable of type 'File'.'
Is there anyway of converting an xfile to a file type?
here is the code coursing the problem
imageSelectorGallery() async {
galleryFile = await ImagePicker.pickImage(
source: ImageSource.gallery,
maxHeight: 50.0,
maxWidth: 50.0,
);
setState(() {});
}
here is the full code
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new GalleryAccess(),
debugShowCheckedModeBanner: false,
);
}
}
class GalleryAccess extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new GalleryAccessState();
}
}
class GalleryAccessState extends State<GalleryAccess> {
late File galleryFile;
#override
Widget build(BuildContext context) {
//display image selected from gallery
imageSelectorGallery() async {
galleryFile = await ImagePicker.pickImage(
source: ImageSource.gallery,
maxHeight: 50.0,
maxWidth: 50.0,
);
setState(() {});
}
return new Scaffold(
appBar: new AppBar(
title: new Text('Gallery Access'),
backgroundColor: Colors.green,
actions: <Widget>[
Text("GFG",textScaleFactor: 3,)
],
),
body: new Builder(
builder: (BuildContext context) {
return Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new RaisedButton(
child: new Text('Select Image from Gallery'),
onPressed: imageSelectorGallery,
),
SizedBox(
height: 200.0,
width: 300.0,
child: galleryFile == null
? Center(child: new Text('Sorry nothing selected!!'))
: Center(child: new Image.file(galleryFile)),
)
],
),
);
},
),
);
}
}
First of all you have to take galleryFile as XFile type and wherever you want to use that picked Xfile then use like below code.
SizedBox(
height: 200.0,
width: 300.0,
child: galleryFile == null
? Center(child: new Text('Sorry nothing selected!!'))
: Center(child: new Image.file(File(galleryFile.path))))

How To Use Start Image stream method from the camera class

I am a newbie in flutter and this is my first real use app.
This is what i want to achieve my app is going to be used to detect number-plates automatically when the camera would be pointed on the numberplate, for the text detection part i am going to use flutter ml kit. How should i write the start image stream method if i want the output of 10 images in the File data type which I would then add to my ImagePathList.
I did do research on this, but i did not find anything related to what i wanted to achieve, there are a few blog posts using this but they have not explained it properly so i turned to stack overflow.
I want the functionality to be like this
This is what my camera_screen looks like
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:firebase_ml_vision/firebase_ml_vision.dart';
import 'package:flutter/services.dart';
import 'package:npgroups/npgroups.dart';
import 'package:society_app/screens/result_screen.dart';
import 'package:society_app/widgets/common_drawer.dart';
import 'package:camera/camera.dart';
import 'dart:async';
import 'package:numeric_keyboard/numeric_keyboard.dart';
class CameraScreen extends StatefulWidget {
final CameraDescription camera;
static String id = 'camera_screen';
CameraScreen({required this.camera});
#override
_CameraScreenState createState() => _CameraScreenState();
}
class _CameraScreenState extends State<CameraScreen> {
Widget buildButton(String buttonText){
return Container(
height: MediaQuery.of(context).size.height * 0.1 * 0.85,
color: Colors.blueAccent,
child: FlatButton(
onPressed: () {},
child: Text(
buttonText,
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.normal,
color: Colors.white
),
)
),
);
}
late CameraController _controller;
late Future<void> _initializeControllerFuture;
late Npgroups _npgroups;
List imagePathList = [];
List<String?> detectedWordList = [];
static const MethodChannel _channel = const MethodChannel('tflite');
String? resultText;
late int imageHeight;
late int imageWidth;
bool? get isPaused => null;
#override
void initState() {
// TODO: implement initState
super.initState();
_controller = CameraController(
// Get a specific camera from the list of available cameras.
widget.camera,
// Define the resolution to use.
ResolutionPreset.medium,
);
_initializeControllerFuture = _controller.initialize();
initPlatformState();
}
Future<void> initPlatformState() async {
_npgroups = Npgroups(listenToNumplate);
await _npgroups.startListening();
}
#override
void dispose() {
// Dispose of the controller when the widget is disposed.
_controller.dispose();
super.dispose();
}
Future getNumberPlate(image) async {
FirebaseVisionImage mlImage = FirebaseVisionImage.fromFile(image);
TextRecognizer recognizeText = FirebaseVision.instance.textRecognizer();
VisionText readText = await recognizeText.processImage(mlImage);
for (TextBlock block in readText.blocks) {
for (TextLine line in block.lines) {
for (TextElement word in line.elements) {
resultText = word.text;
_npgroups.processNumberplate(resultText!);
}
}
}
if (resultText == null) {
print('null');
} else {
detectedWordList.add(resultText);
}
}
listenToNumplate(String numplate) {
//Consume the numplate
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: CommonDrawer(),
appBar: AppBar(
title: Text(
'Camera'
),
),
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
AspectRatio(aspectRatio: _controller.value.aspectRatio - 0.2,
child: CameraPreview(_controller)),
Positioned(
bottom: 10,
left: 5,
child: Row(
children: [
VehicleButton(icon: Icons.motorcycle_outlined,),
SizedBox(width: 35),
VehicleButton(icon: Icons.directions_car,)
],
),
)
],
),
Row(
children: [
Container(
width: MediaQuery.of(context).size.width * .99,
child: Table(
children: [
TableRow(
children: [
buildButton('1'),
buildButton('2'),
buildButton('3')
]
),
TableRow(
children: [
buildButton('4'),
buildButton('5'),
buildButton('6')
]
),
TableRow(
children: [
buildButton('7'),
buildButton('8'),
buildButton('9')
]
),
TableRow(
children: [
buildButton('↻'),
buildButton('0'),
buildButton('⌫')
]
),
],
),
)
],
)
],
);
} else {
// Otherwise, display a loading indicator.
return const Center(child: CircularProgressIndicator());
}
},
),
);
}
}
class VehicleButton extends StatelessWidget {
final IconData icon;
VehicleButton({required this.icon});
#override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 17, horizontal: 50),
child: Icon(
icon,
color: Colors.white,
size: 45,
),
),
style: ButtonStyle(
shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)))
),
);
}
}
Blockquote
You can do something like that
#override
void initState() {
super.initState();
controller = CameraController(widget.cameras[0], ResolutionPreset.medium,
enableAudio: false);
controller.initialize().then((_) async {
if (!mounted) {
return;
}
setState(() {});
await controller.startImageStream((CameraImage availableImage) async {
_scanText(availableImage);
});
}

How to solve it when Flutter MaterialPageRoute navigates to a screen with black background?

I'm using Flutter for first time for one of my projects which is a Newspaper App.
The problem takes place when I try to navigate from main.dart to newsfeed_for_other_category.dart using MaterialPageRoute from my Drawer. In that screen it shows the news but with a black background. But in the screen newsfeed_screen.dart which is called in the body in my main.dart it shows perfectly.
I'm posting the codes below.
main.dart
import 'package:flutter/material.dart';
import './SizeConfig.dart';
import './screens/newsfeed_screen.dart';
import 'package:curved_navigation_bar/curved_navigation_bar.dart';
import 'factory/widget_factory.dart';
import 'widgets/top_news_widget.dart';
import 'package:splashscreen/splashscreen.dart';
import './widgets/drawer.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Newspaper App',
theme: ThemeData(
primarySwatch: Colors.blue,
//backgroundColor: Colors.lightGreenAccent,
),
home: MyHomePage(title: 'The Business Standard'),
routes: <String, WidgetBuilder> {
'/screen1': (BuildContext context) => new NewsFeedScreen(216, 5, "Top News"),
'/screen2' : (BuildContext context) => new NewsFeedScreen(4, 7, "National"),
'/screen3' : (BuildContext context) => new NewsFeedScreen(13, 70, "International"),
/*'/screen4' : (BuildContext context) => new Screen4()*/
},
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: '_MainScreenKey');
Widget build(BuildContext context) {
return SplashScreen(
seconds: 3,
navigateAfterSeconds: AfterSplash(),
title: Text(
'The Business Standard',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0
),
),
image: Image.asset(
'assets/TBS_logo.jpg',
),
backgroundColor: Colors.white,
styleTextUnderTheLoader: TextStyle(),
photoSize: 100.0,
onClick: ()=>print("Flutter Egypt"),
loaderColor: Colors.red
);
}
}
class AfterSplash extends StatefulWidget {
#override
_AfterSplashState createState() => _AfterSplashState();
}
class _AfterSplashState extends State<AfterSplash> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: '_MainScreenKey');
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
backgroundColor: Colors.white,
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Image.asset(
'assets/TBS.png',
fit: BoxFit.cover,
height: 45,
)
],
),
leading: IconButton(
icon: Icon(Icons.dehaze),
color: Colors.black,
onPressed: () => _scaffoldKey.currentState.openDrawer(),
),
),
drawer: SideDrawer(),
body: NewsFeedScreen(22, 71, "Sports"),
bottomNavigationBar: CurvedNavigationBar(
backgroundColor: const Color(0xFF2b4849),
items: <Widget>[
Icon(Icons.bookmark, size: 30,),
Icon(Icons.perm_identity, size: 30,),
Icon(Icons.settings, size: 30,),
],
onTap: (index) {
if(index == 2) {
_scaffoldKey.currentState.showSnackBar(const SnackBar(
content: const Text('Will open Settings menu')));
} else if(index == 0) {
_scaffoldKey.currentState.showSnackBar(const SnackBar(
content: const Text('Implement Bookmark function')));
} else {
_scaffoldKey.currentState.showSnackBar(const SnackBar(
content: const Text('Will show User profile and information')));
}
},
),
);
}
}
newsfeed_for_other_category.dart, the page to which I'm navigating and this is where the black background shows up.
import 'package:flutter/material.dart';
import '../SizeConfig.dart';
import '../widgets/headlines.dart';
import '../widgets/secondary_headlines.dart';
import '../widgets/listed_news.dart';
import '../models/NewsPost.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:developer';
import '../screens/newsPost_details.dart';
import '../screens/newsfeed_for_specific_category.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import '../transition_animation_routes/ScaleTransitionRoute.dart';
import '../widgets/top_news_widget.dart';
class NewsfeedForOtherCategory extends StatefulWidget {
int categoryId;
int childrenCategoryId;
String categoryName;
NewsfeedForOtherCategory(this.categoryId, this.childrenCategoryId, this.categoryName);
#override
_NewsfeedForOtherCategoryState createState() => _NewsfeedForOtherCategoryState(this.categoryId, this.childrenCategoryId, this.categoryName);
}
class _NewsfeedForOtherCategoryState extends State<NewsfeedForOtherCategory> {
int categoryId;
int childrenCategoryId;
String categoryName;
_NewsfeedForOtherCategoryState(this.categoryId, this.childrenCategoryId, this.categoryName);
bool _isRequestSent = false;
List<NewsPost> newsPostList = [];
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
if(!_isRequestSent) {
_sendRequest();
}
return Container(
alignment: Alignment.center,
child: !_isRequestSent
? CircularProgressIndicator()
: Container(
child: ListView.builder(
itemCount: newsPostList.length,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
return _getNewsPostWidgets(index);
}
),
),
);
}
void _sendRequest() async {
String url = "https://tbsnews.net/json/category/news/"+this.categoryId.toString()+"/"+this.childrenCategoryId.toString()+"";
http.Response response = await http.get(url);
List<dynamic> decode = json.decode(response.body);
log('response: $response');
List results = decode[0]['items'];
for (var jsonObject in results) {
var post = NewsPost.getNewsPostFromAPI(jsonObject);
newsPostList.add(post);
print(post);
}
setState(() => _isRequestSent = true);
}
Widget _getNewsPostWidgets(int index) {
var newsPost = newsPostList[index];
if(index < this.newsPostList.length) {
if(index == 0) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
ScaleTransitionRoute(
page: NewsPostDetails(newsPostList, index)
)
);
},
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
//constraints: BoxConstraints(minWidth: double.infinity, maxWidth: double.infinity),
constraints: BoxConstraints.expand(
width: double.infinity,
height: 40
),
color: const Color(0xFF2b4849),
child: Text(
this.categoryName,
style: TextStyle(
fontSize: 33,
color: Colors.white
),
),
),
BlockHeadline(newsPost)
],
)
);
}
else {
return GestureDetector(
onTap: () {
Navigator.push(
context,
ScaleTransitionRoute(
page: NewsPostDetails(newsPostList, index)
)
);
},
child: ListedNews(newsPost),
);
}
}
else {
return Container(
color: const Color(0xFF2b4849),
child: index == 3 ? FlatButton(
child: Text(
"Load More",
style: TextStyle(
color: Colors.white
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => NewsFeedForSpecificCategory(newsPostList)
)
);
},
) : Container(),
);
}
}
openNewsPostDetails(List<NewsPost> newsPostList, int index) {
Navigator.push(
context,
ScaleTransitionRoute(
page: NewsPostDetails(newsPostList, index)
)
);
}
}
drawer.dart
import 'package:flutter/material.dart';
import '../SizeConfig.dart';
import '../screens/newsfeed_for_other_category.dart';
class SideDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return SizedBox(
width: SizeConfig.safeBlockHorizontal*50,
child: Theme(
data: Theme.of(context).copyWith(canvasColor: const Color(0xFF2b4849)),
child: Drawer(
child: ListView(
children: <Widget>[
ListTile(
title: Text(
'Top News',
style: TextStyle(
fontSize: 20,
color: Colors.white
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => NewsfeedForOtherCategory(216, 5, "Top News")
)
);
},
),
],
),
),
),
);
}
}
In my home screen which is newsfeed_screen.dart called in the body of AfterSplashState widget in main.dart it looks like below, this is what it should look like.
But in the screen NewsfeedForOtherCategory to which I navigate using drawer looks like below with the black background.
I have tried using Navigator.of(context, rootNavigator: true).pushNamed('/route') and pushReplacementNamed() also instead of MaterialPageRoute. But of no use.
Here is a related question that I found, I tried the solutions they gave, but did not work for me.
Also to mention, the page I'm navigating to does not have MaterialApp widget, only the main.dart has it. So there should not be an issue.
I'm using a Ubuntu 16.04 machine.
Some clue from you would be priceless. Thanks a lot for your time.
NewsfeedForOtherCategory page is black because it doesn't have Material container.
You can simply wrap it with Material widget or Scaffold(which has some additional features like drawer, floating action button).
And from your screenshot I can see some widgets are overflowed by notification bar. You can use SafeArea inside Material or inside body of the Scaffold to overcome this.
Wrap the main Container in NewsfeedForOtherCategory with a scaffold and you have your solution.
...
return Scaffold(
body: Container(
alignment: Alignment.center,
child: !_isRequestSent
? CircularProgressIndicator()
: Container(
child: ListView.builder(
itemCount: newsPostList.length,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
return _getNewsPostWidgets(index);
}
),
),
);
);
...
In the build function of your NewsfeedForOtherCategory widget,
try wrapping what you have there in a Scaffold.
Like:
return Scaffold(
body: Container(
alignment: Alignment.center,
child: !_isRequestSent
? CircularProgressIndicator()
: Container(
child: ListView.builder(
itemCount: newsPostList.length,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
return _getNewsPostWidgets(index);
}),
),
),
),
when we navigate between two screen both screen parent should be scafold
if you don't want to use scaffold u can use container color property also
Try wrapping your container in scaffold in NewsfeedForOtherCategory screen Like this
...
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
),
);
}
...
Or u can set container color white like this
...
#override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child:
//enter code here
);
}
...

Categories

Resources