How do I handle screen parameters in themedata's routes? - flutter

I want to use ThemeData and set routes at
routes: {
'/': (context) => const LoginScreen(),
'/sign-up-screen': (context) => const SignUpScreen(),
'/sign-in-screen': (context) => const SignInScreen(),
'/map-screen': (context) => MapScreen()}
But I also have a screen with parameters, like this.
import 'dart:io';
import 'package:dash_mement/poststory/check_image.dart';
import 'package:dash_mement/providers/pushstory_provider.dart';
import 'package:dash_mement/style/mmnt_style.dart';
import 'package:dash_mement/style/story_textstyle.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart';
class PostImage extends StatelessWidget {
Widget _inform = Image.asset("assets/images/check_image.png");
final ImagePicker _picker = ImagePicker();
late Function _backButton;
double? lat_y;
double? lng_x;
PostImage(this._backButton) {}
PostImage.newPin({required double latitude_y, required double longitude_x}) {
lat_y = latitude_y;
lng_x = longitude_x;
}
....
}
How can I add this screen at ThemeData's routes of main.dart

Add it like any other route and access arguments in a widget something like this:
class PostImage extends StatelessWidget {
...
#override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments;
Or alternatively use onGenerateRoute to handle routes and extract arguments and pass to a widget.
See Pass arguments to a named route for details.

Related

How can I import Riverpod StateNotifier from separate file?

- src/main.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
class AnotherWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Consumer(
builder: (context, watch, _) {
},
);
}
}
I want to take city to another file with other StateProviders.
- src/controller/states.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
final city = StateProvider<String>((ref) => 'NYC');
final currency = StateProvider<String>((ref) => 'USD');
If I take final city from main.dart and move it to states.dart, how can I make them available to main.dart? I've tried to access these states, but it does not recognize it.

Flutter Unit Class with Initializer

I'm trying to write the unit test for this class, but I'm having problems about the initializer... When I instantiate the class in the test file, the caller throws an error that " Null check operator used on a null value". I know that's because the UserProvider is not initialized on the test folders. But how can I mock this??
class ContactController extends ChangeNotifier {
BuildContext context;
ContactController(this.context) {
initializeData();
}
late Contact contact;
initializeData() {
var userProvider = context.read<UserProvider>();
var currentContact = userProvider?.contact;
if (currentContact != null) {
newContact = currentContact;
}
notifyListeners();
}
}
The code below should do the trick. The thing is that you need to provide a mocked UserProvider into the context. To do so, just use MultiProvider in the tests to inject the mocked one.
Note the use of #GenerateMocks([UserProvider]). This comes from mockito and it annotates the source to generate the MockUserProvider class. And to generate the *.mocks.dart just run flutter pub run build_runner build.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:provider/provider.dart';
import 'package:so72756235_test_provider/contact_controller.dart';
import 'contact_controller_test.mocks.dart';
#GenerateMocks([UserProvider])
void main() {
testWidgets('ContactController test', (WidgetTester tester) async {
final mockUserProvider = MockUserProvider();
when(mockUserProvider.contact).thenReturn(const Contact(name: 'Test'));
await tester.pumpWidget(
MultiProvider(
providers: [
Provider<UserProvider>(create: (_) => mockUserProvider),
ChangeNotifierProvider(
create: (context) => ContactController(context)),
],
child: Consumer<ContactController>(
builder: (context, value, child) =>
Text(value.newContact.name, textDirection: TextDirection.ltr)),
),
);
expect(find.text('Test'), findsOneWidget);
});
}

How can I call an Encrypted Hive Box to a class?

I am needing to encrypt a hive box, in which the box 'user_api' is to be called in Api_Page_() to receive user input to store inside said box. However, the encryptedBox is not defined within the class. The Hive Docs display the encryption code is to be done inside of the main() function, which I have done, but I am unsure of how to take the box outside of main().
Any help or advice is greatly appreciated!
My Code:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// HIVE ENCRYPTION----------------------------------------
const secureStorage = FlutterSecureStorage();
final encryptionKey = await secureStorage.read(key: 'key');
if (encryptionKey == null) {
final key = Hive.generateSecureKey();
await secureStorage.write(
key: 'key',
value: base64Encode(key),
);
}
final key = await secureStorage.read(key: 'key');
final encryptKey = base64Url.decode(key);
print('Encryption key: $encryptKey');
// HIVE ENCRYPTION----------------------------------------
// HIVE INIT---------------------------------------------
Directory directory = await getApplicationDocumentsDirectory();
Hive.init(directory.path);
await Hive.initFlutter();
final encryptedBox = Hive.openBox<String>('user_api', encryptionCipher: HiveAesCipher(encryptKey)); // Initially Opens Box on App Start
// HIVE INIT---------------------------------------------
runApp(myApp());
}
class myApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false, // Removes Debug Banner. [Delete before app release]
title: 'App Title Placeholder',
home: API_Page_() // Calls API_Page_ class from api_page.dart
);
}
}
class API_Page_ extends StatelessWidget {
const API_Page_({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: RaisedButton(onPressed: () { var eBox = encryptedBox<String>('user_api');
},
)
);
}
}

How to use same Future another .dart file? (Flutter)

I'd like to use Future teamMember() in another .dart file. Any contributions are welcome!
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';
void main() {
runApp(new MaterialApp(
home: new Popups(),
));
}
class Popups extends StatefulWidget {
#override
_PopupsState createState() => _PopupsState();
}
class _PopupsState extends State<Popups> {
Future teamMember() async {
await showDialog(
context: context,
...
...
In the other class where you need it create a reference to your popup class and then call teamMember.
class OtherClass extends StatelessWidget {
Popups _popups = Popups();
.
.
RaisedButton(
child: Text("show team member popup"),
onPressed: (){
_popups.teamMember();
}
)
}
hope this helps

How to pass a class instance reference as a generic type in flutter

My objective is to create a method that would take the arguments of the buildcontext and screen reference and rout it accordingly with the provided details. My partially in complete code as bellow. help would much appreciate.
My Helper class
import 'package:flutter/material.dart';
class Utils {
static routToPage <T> (BuildContext context, <T> page){
Navigator.of(context).push(MaterialPageRoute(builder: (context) =>page);
}
}
The class I wants to access it
import './utils'
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
navigateToPage(){
Utils.rout(BuildContext context, PageTwo())
}
}
For now as the syntax are wrong I'm stuck with my approach.
Well, I think no need to create static class. Here is a working example.
Paste the below method in a dart file.
void navigateToScreen(BuildContext context, Widget widget) {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => widget,
));
}
And use the class for navigating, like
navigateToScreen(buildContext, YourNavigationScreen());
I prefer using Widget as a object parameter instead of <T>.
Also you can check the easiest way navigate to another page by using route like this.
Create Route in (yourproject)/lib/route/routes.dart
import './page/main_page.dart';
import './page/one_page.dart';
import './page/two_page.dart';
final routes = {
'/': (BuildContext context) => MainPage(),
'/pageone': (BuildContext context) => PageOne(),
'/pagetwo': (BuildContext context) => PageTwo(),
}
Main Page in (yourproject)/lib/main.dart
import './route/routes.dart';
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIOverlays([]);
return MaterialApp(
initialRoute: '/', // the default route is MainPage()
routes: routes,
);
}
}
When navigating to other page you can simply use either one of these Navigator.pushNamed, Navigator.popAndPushNamed, Navigator.pushNamedAndRemoveUntil, Navigator.pushReplacementNamed do like this
// your can simple change the route of your choice by changing the name of route
Navigator.pushNamed(context, '/pageone');
Navigator.popAndPushNamed(context, '/pagetwo');
...