简体   繁体   中英

How can I create a generic Dart Library?

I have 2 apps that require authentication and I am trying to create a "reusable" authentication library.

app1.dart

import 'package:myLibrary/login_page.dart';

class App1 extends StatefulWidget {
  @override
  _App1State createState() => _App1State();
}

class _App1State extends State<App1> {

  bool authenticated = false;

  @override
  Widget build(BuildContext context) {
    if (authenticated) {
      return Scaffold(...);
    } else {
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => return LoginPage()));
    }  
  }
}

app2.dart (pretty much same structure)

import 'package:myLibrary/login_page.dart';

class App2 extends StatefulWidget {
  @override
  _App2State createState() => _App2State();
}

class _App2State extends State<App2> {

  bool authenticated = false;

  @override
  Widget build(BuildContext context) {
    if (authenticated) {
      return Scaffold(...);
    } else {
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => return LoginPage()));
    }  
  }
}

myLibrary/login_page.dart

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final _auth = FirebaseAuth.instance;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Autentication'),
        ),
      ),
      body: SafeArea(
        ...
        if (userCredential != null) {
          setState(() {
            _isLoading = false;
          });
          Navigator.pushReplacement(
            context,
            MaterialPageRoute(
            builder: (context) => AnyApp()),        <--- PROBLEM Here!
         );
        } else {
          //Show login failed
        }

The problem is that AnyApp() needs to be mapped to the class that called the library.

As far as I gathered from similar questions, passing a Class is not allowed.

So is this doable?

This is how I implemented @Levi Lesches' suggestion, and it solved the issue.

main.dart

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:myApp/home_page/home_page.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  // Create route to supply to generic Login package
  MaterialPageRoute materialPageRoute = MaterialPageRoute(builder: (context) => HomePage());

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: themeECL,
      // Pass specific Route to generic LoginPage
      home: LoginPage(materialPageRoute: materialPageRoute),
    );
  }
}

myLibrary/login_page.dart

class LoginPage extends StatefulWidget {
  //Add argument to pass Route on successful login
  const LoginPage({
    Key? key,
    required this.materialPageRoute,
  }) : super(key: key);

  final MaterialPageRoute materialPageRoute;
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final _auth = FirebaseAuth.instance;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Autentication'),
        ),
      ),
      body: SafeArea(
        ...
        if (userCredential != null) {
          setState(() {
            _isLoading = false;
          });
          Navigator.pushReplacement(
            context,
            widget.materialPageRoute        <--- Solution Here!
         );
        } else {
          //Show login failed
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM