[FlutterWeb] #4 라이팅, 네비게이션steemCreated with Sketch.

in hive-138689 •  2 years ago 

플러터 웹 개발 시리즈 4번째.

이전글

[FlutterWeb] #3 Light, Dark Mode 변환 구현

1. 라우팅

사용자가 브라우저 주소창에 입력하는 주소에 맞는 스크린을 표시해줘야 한다. 이것을 라우링(Routing)이라고 한다.

라우팅에서 중요한 것은 동적 라우팅이다. 주소가 고정되어 있고, 지정된 스크린으로 이동하는 것은 매우 간단하다. 플러터 웹 자료 중 대부분이 정적 라우팅에 대해서 다루고 있다. 동적 라우팅을 다루는 자료는 많지 않다.

웹이다 보니 동적 라우팅은 필연적이다.

여기서는 정적 라우팅과 동적 라우팅을 처리하기 위한 내용을 다룬다. 라우팅을 위해서 이전에 소개한 Get 패키지를 사용한다.

  • 다음과 같이 main.dart에서 라우팅을 설정한다.
class AppWidget extends StatelessWidget {
  const AppWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'AVLE Able',
      theme: AvleThemes.lightTheme,
      darkTheme: AvleThemes.darkTheme,
      themeMode: ThemeMode.light,
      debugShowCheckedModeBanner: false,
      initialRoute: Routes.home,
      onGenerateRoute: RouteConfiguration.onGenerateRoute,
    );
  }
}

위 코드를 보면 Routes.home과 onGenerateRoute가 설정되어 있는데 이것은 다음 과 같이 routes/app_routes.dart 파일에 작성한다.

// 라우트 이름
abstract class Routes {
  static const home = '/';
  static const creator = '/creator';
}

// Regex for routes
class RouteRegex {
  static const String creator = r'^/@([\w.\d-]+)';
}


// 동적 라우팅을 다루기 위한 Paht 클래스
class Path {
  const Path(this.pattern, this.builder);

  /// A RegEx string for route matching.
  final String pattern;

  /// The builder for the associated pattern route. The first argument is the
  /// [BuildContext] and the second argument is a RegEx match if it is
  /// included inside of the pattern.
  final Widget Function(BuildContext, String?) builder;
}

class RouteConfiguration {
  static List<Path> paths = [
    // navigate to creator screen
    Path(
      RouteRegex.account,
      (context, match) {
        print('app_routes. account route. match: $match');
        if (match != null) {
          print('app_routes. account route. has match: $match');
          return CreatorScreen(slug: match);
        }
        return Container();
      },
    ),

    // navigate to Home screen
    Path(
      r'/',
      (context, match) => const HomeScreen(),
    ),
  ];


  static Route<dynamic>? onGenerateRoute(RouteSettings settings) {
    final currentRoute = settings.name!;
    // match path
    for (Path path in paths) {
      final regExpPattern = RegExp(path.pattern);
      if (regExpPattern.hasMatch(currentRoute)) {
        final firstMatch = regExpPattern.firstMatch(currentRoute);
        final match = (firstMatch!.groupCount > 0) ? firstMatch.group(0) : null;
        return MaterialPageRoute<void>(
          builder: (context) => path.builder(context, match),
          settings: settings,
        );
      }
    }

    // If no match was found, we let [WidgetsApp.onUnknownRoute] handle it.
    return null;
  }
}

네비게이션

HomeScreen에 텍스트 버튼을 하나 추가해서 다음과 같이 버튼을 눌렀을 때 '@etainclub' 페이지로 이동하게 한다.

 TextButton(
              onPressed: () {a
                Get.to(() => const CreatorScreen(slug: '/@etainclub'),
                    routeName: '/@etainclub');
              },
              child: Text('Visit a Creator @etainclub'),
            ),

여기서 보면 Get 패키지가 사용되었다. 테스트를 위해서 url을 고정했다. 향후 이것을 동적으로 변경하여 입력할 수 있게 하면 된다. Get 패키지를 사용하면 어디서든 저렇게 하여 간단히 페이지 네비게이션이 가능하며, 매개변수를 전달할 수도 있다.


3. CreatorScreen

CreatorScreen을 테스트 용으로 간단히 만든다. 중요한 것은 slug로 입력되는 변수를 파싱하여 계정이름을 뽑아서 화면에 표시해주는 부분이다.

class CreatorScreen extends StatefulWidget {
  const CreatorScreen({required this.slug, Key? key}) : super(key: key);
  final String slug;

  @override
  State<CreatorScreen> createState() => _CreatorScreenState();
}

class _CreatorScreenState extends State<CreatorScreen> {
  String? creator;

  @override
  void initState() {
    super.initState();
    //// get author from slug
    final accountRegex = RegExp(RouteRegex.account);
    print('creator screen. slug: ${widget.slug}');
    if (accountRegex.hasMatch(widget.slug)) {
      // get author from the slug
      final stringMatch = accountRegex.stringMatch(widget.slug).toString();
      print('creator screen. string match: $stringMatch');
      if (stringMatch.isNotEmpty) {
        creator = stringMatch.split('/@')[1];
        printWarning('creator init match. author: $creator');
      } else {
        creator = null;
      }
    } else {
      // Get.back();
    }
  }

  @override
  Widget build(BuildContext context) {
    print('splash screen builder');
    return Scaffold(
      body: Center(
        child: Text('Creator @$creator Screen'),
      ),
    );
  }
}

위 코드에서 입력된 slug로부터 계정명만 추출하여 화면에 표시하고 있다.

4. 테스트

HomeScreen에서 CreatorScreen으로 네이게이션 하는 버튼을 눌러 보자.


위 그림에서 주소창의 url을 잘 보라. 스팀잇의 주소형태를 띠고 있다. 이 url이 파싱되어 CreatorScreen으로 이동하고, 이 때 전달되는 slug의 값을 파싱해서 계정명을 화면에 표시해준다.

정리

플러터 웹에서 동적 url을 라우팅하여 적절한 screen으로 네이게이션 하는 코드를 구현했다. 이를 이용하면 사용자가 브라우저 주소창에 입력하는 url을 적절히 처리할 수 있다.

Please vote for me as a witness and Resteem this post

Thank you everyone for voting.

https://steemitwallet.com/~witnessesimage.png

@steemcurator01, Thank you for Your Support

cc.
@pennsif


Posted through the AVLE Dapp (https://avle.io)

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Thank you, friend!
I'm @steem.history, who is steem witness.
Thank you for witnessvoting for me.
image.png
please click it!
image.png
(Go to https://steemit.com/~witnesses and type fbslo at the bottom of the page)

The weight is reduced because of the lack of Voting Power. If you vote for me as a witness, you can get my little vote.

라우팅 하다 짜증나면 샤우팅

어떻게 알았지? 지금 라우팅때문에 샤우팅하게 생겼네!