Flutter Web - 새로 고침 및 뒤로 버튼 문제 수정

14143 단어 webflutterrefreshback


업데이트 공지!!!



아래 설명은 다소 구식입니다. 이제 Flutter Navigation 2.0을 사용하는 라우팅 패키지인 go_router 을 사용하는 것이 좋습니다!

소개



Flutter 웹에 있을 때 라우팅 문제에 직면했습니다. MaterialAppGetMaterialApp 모두 동일한 문제가 있었는데, 브라우저의 뒤로 버튼과 새로 고침 버튼을 클릭하면 라우팅이 이상하게 작동했습니다. 그래서 플러터 웹으로 몇 가지 테스트 프로젝트를 시도했고 해결책을 찾았습니다. 이제 네이티브 웹 프로젝트처럼 작동합니다. 이 솔루션을 여러분과 공유하고 싶습니다.

플러터 내비게이션 2.0


Flutter Navigation 2.0라는 것이 있습니다. 나는 그것에 대해 많이 파헤치지 않았지만 간단히 말해서 내비게이션 시스템은 이제 이 내비게이션 2.0으로 더 많은 사용자 정의가 가능합니다.

원래 라우팅 시스템은 웹 플랫폼에서 너무 많은 문제가 있었기 때문에 이것을 시도해야 했습니다. 고맙게도 작동했습니다. 그냥 MaterialApp.router 대신 MaterialApp 와 함께 사용할 수 있습니다. 그러나 그렇게 하는 경우 탐색 논리와 관련된 일부 재정의 메서드를 구현해야 합니다. 각 메서드를 재정의하는 대신 기본 메서드와 함께 제공되는 GetMaterialApp.router를 사용했으므로 추가 작업은 메서드를 빌드하는 것뿐입니다.

코드 구현



Getx 설치



이때는 아래 버전Getx 패키지를 사용했습니다.

dependencies:
  ...
  get: ^4.6.1


기본 라우팅 항목



편의상 간단한 라우팅 경로와 스니펫이 있는 getPages를 사용했습니다.

abstract class Routes {
  static const HOME = '/';
  static const LOGIN = '/login';
  static const SIGNUP = '/signup';
}




abstract class AppPages {
  static final pages = [
    GetPage(
      name: Routes.HOME,
      page: () => Home(),
    ),
    GetPage(
      name: Routes.LOGIN,
      page: () => Login(),
    ),
    GetPage(
      name: Routes.SIGNUP,
      page: () => Signup(),
    ),
  ];
}


GetMaterialApp.router 생성


GetMaterialApp.router 대신 GetMaterialApp 를 사용하면 initialRoute 를 제공할 필요가 없습니다(그리고 제공할 수도 없습니다). 그러나 getPagesrouterDelegate 필드에 값을 제공해야 합니다.

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(GetMaterialApp.router(
    debugShowCheckedModeBanner: false,
    defaultTransition: Transition.fade,
    getPages: AppPages.pages,
    routerDelegate: AppRouterDelegate(),
  ));
}


샘플 페이지 만들기



테스트를 위해 배경색이 다른 몇 가지 간단한 테스트 페이지를 만들었습니다.
  • 페이지 사이를 이동할 때 Get.rootDelegate를 사용하여 라우팅을 처리하므로 Get 대신 routerDelegate를 사용해야 합니다.

  • class Home extends StatelessWidget {
      const Home({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.red,
          child: TextButton(
            child: Text(
              'Home',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () => Get.rootDelegate.toNamed(Routes.LOGIN),
          ),
        );
      }
    }
    
    class Login extends StatelessWidget {
      const Login({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.orange,
          child: TextButton(
            child: Text(
              'Login',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () => Get.rootDelegate.toNamed(Routes.SIGNUP),
          ),
        );
      }
    }
    
    class Signup extends StatelessWidget {
      const Signup({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.blue,
          child: TextButton(
            child: Text(
              'Signup',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () => Get.rootDelegate.toNamed(Routes.HOME),
          ),
        );
      }
    }
    


    GetDelegate로 라우터 델리게이트 생성



    그래서 이것이 주요 부분입니다.
  • AppRouterDelegate를 만들거나 GetDelegate 확장으로 전화하고 싶은 것을 만드세요.
  • build 메서드를 재정의하고 NavigatoronPopPagepages를 반환합니다.
  • onPopPage → 팝 액션이 발생했을 때 호출되며, 팝 성공 여부에 관계없이 반환됩니다. 팝 액션을 차단하지 않으려면 기본 코드로 그대로 두십시오.
  • pagesgetPages와는 다릅니다. 이것은 현재 순간에 표시할 페이지와 더 관련이 있습니다. 아직 완전히 파악되지는 않았지만 내비게이션 히스토리 스택과도 다릅니다. 그래서 현재 url에 맞는 페이지를 보여주기 위해 currentConfiguration.currentPage를 사용했습니다. 이 필드는 현재 보기와 관련되어 있으므로 비워둘 수 없습니다. currentConfiguration가 null일 때(즉, 페이지에 처음 들어왔다는 의미), 단순히 초기 페이지로 돌아갈 수 있습니다.


  • 
    class AppRouterDelegate extends GetDelegate {
      @override
      Widget build(BuildContext context) {
        return Navigator(
          onPopPage: (route, result) => route.didPop(result),
          pages: currentConfiguration != null
              ? [currentConfiguration!.currentPage!]
              : [GetNavConfig.fromRoute(Routes.HOME)!.currentPage!],
        );
      }
    }
    


    또한 build 방법 및 기타 재정의 방법(로그인을 사용자 지정하려는 경우)을 작성할 수 있으므로 페이지로 이동하기 전에 사용자 인증 상태 확인을 쉽게 추가할 수 있습니다.

    결론



    Flutter Web이 갈 길이 멀다고 생각하지만 Flutter가 계속해서 작업하고 있어 기쁩니다! 이 기사가 Flutter 웹 라우팅 문제로 어려움을 겪는 사람들에게 도움이 되기를 바랍니다.

    건배!

    좋은 웹페이지 즐겨찾기