ตอนที่ 5 ทำแอพ Flutter : การนำทาง (Navigation) และการกำหนดเส้นทาง (Routing)

  1. แนวคิดการนำทางพื้นฐาน
  2. เส้นทาง (Routes)
  3. เส้นทางที่มีชื่อ (Named Routes)
  4. การส่งผ่านข้อมูลระหว่างเส้นทาง
  5. OnGenerateRoute และ OnUnknownRoute
  6. การเปลี่ยนเส้นทาง (Route Transitions)

การนำทาง (Navigation) และการกำหนดเส้นทาง (Routing) เป็นส่วนประกอบที่สำคัญของการทำแอพมือถือใดๆ ใน Flutter ระบบนำทางจะช่วยจัดการการเปลี่ยนผ่านระหว่างหน้าจอหรือหน้าต่างๆ ทำให้ผู้ใช้สามารถโต้ตอบกับแอพได้อย่างราบรื่น บทความนี้จะเจาะลึกแนวคิดที่สำคัญของการนำทางและการกำหนดเส้นทางในการทำแอพ Flutter โดยสาธิตวิธีการใช้การนำทางพื้นฐาน จัดการเส้นทาง และสร้างการเปลี่ยนแบบกำหนดเอง เริ่มต้นการเดินทางครั้งนี้และสำรวจโลกแห่งการนำทางและการกำหนดเส้นทางของ Flutter

1. แนวคิดการนำทางพื้นฐาน

ใน Flutter วิดเจ็ต ‘Navigator’ มีหน้าที่จัดการสแต็กของเส้นทาง (หรือเพจ) ที่ผู้ใช้นำทางผ่าน Navigator ใช้โครงสร้างข้อมูลแบบสแต็กเพื่อรักษาเส้นทาง ทำให้นักพัฒนาสามารถพุชและป๊อปเส้นทางได้ตามต้องการ

ในการนำทางไปยังหน้าจอใหม่ จะใช้วิธี ‘Navigator.push()’ สิ่งนี้ผลักเส้นทางใหม่ไปยังสแต็กของเนวิเกเตอร์ ในการกลับไปยังหน้าจอก่อนหน้า จะใช้วิธี ‘Navigator.pop()’ ซึ่งจะแสดงเส้นทางบนสุดออกจากสแต็ก

2. เส้นทาง (Routes)

‘Routes’ ใน Flutter แสดงถึงหน้าจอหรือหน้าแอพ ‘MaterialPageRoute’ และ ‘CupertinoPageRoute’ เป็นสองคลาสเส้นทางที่ใช้กันทั่วไปซึ่งเป็นไปตามแนวทางการออกแบบ Material และ Cupertino ตามลำดับ

การสร้างเส้นทางพื้นฐานทำได้ดังนี้

class DetailsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Details')),
      body: Center(
        child: Text('Welcome to the Details Screen!'),
      ),
    );
  }
}

ในการนำทางไปยัง ‘DetailsScreen’ ให้ใช้วิธี ‘Navigator.push()’:

Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => DetailsScreen()),
);

3. เส้นทางที่มีชื่อ (Named Routes)

เส้นทางที่มีชื่อเป็นคุณสมบัติสำคัญของระบบการนำทางของ Flutter ทำให้กระบวนการนำทางระหว่างหน้าจอง่ายขึ้น แทนที่จะใช้ ‘MaterialPageRoute’ โดยตรง คุณสามารถกำหนดตัวระบุเฉพาะให้กับเส้นทางได้ ทำให้โค้ดสามารถอ่านและบำรุงรักษาได้มากขึ้น

หากต้องการตั้งค่าเส้นทางที่มีชื่อ ให้อัปเดตวิดเจ็ต ‘MaterialApp’ ในไฟล์ ‘main.dart’:

MaterialApp(
  initialRoute: '/',
  routes: {
    '/': (context) => HomeScreen(),
    '/details': (context) => DetailsScreen(),
  },
);

ตอนนี้ไปที่ ‘DetailsScreen’ โดยใช้เส้นทางที่มีชื่อ:

Navigator.pushNamed(context, '/details');

4. การส่งผ่านข้อมูลระหว่างเส้นทาง

บ่อยครั้งที่คุณต้องส่งข้อมูลระหว่างเส้นทางระหว่างการนำทาง ในการทำเช่นนี้ เพียงอัปเดตตัวสร้างเส้นทางปลายทางให้ยอมรับข้อมูลที่จำเป็น:

class DetailsScreen extends StatelessWidget {
  final String data;

  DetailsScreen({required this.data});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Details')),
      body: Center(
        child: Text('Data passed: $data'),
      ),
    );
  }
}

เมื่อพุชเส้นทาง ให้ส่งข้อมูลเป็นอาร์กิวเมนต์:

Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => DetailsScreen(data: 'Hello, Details!')),
);

5. OnGenerateRoute และ OnUnknownRoute

บางครั้ง คุณอาจต้องควบคุมการสร้างเส้นทางหรือจัดการกับเส้นทางที่ไม่รู้จักมากขึ้น ในกรณีดังกล่าว ให้ใช้การเรียกกลับ ‘onGenerateRoute’ และ ‘onUnknownRoute’ ในวิดเจ็ต ‘MaterialApp’:

MaterialApp(
  initialRoute: '/',
  onGenerateRoute: (settings) {
    if (settings.name == '/details') {
      final String data = settings.arguments as String;
      return MaterialPageRoute(
        builder: (context) => DetailsScreen(data: data),
      );
    }
    return null;
  },
  onUnknownRoute: (settings) {
    return MaterialPageRoute(
      builder: (context) => UnknownRouteScreen(),
    );
  },
);

เมื่อใช้ ‘onGenerateRoute’ คุณสามารถสร้างเส้นทางแบบไดนามิกตาม ‘RouteSettings’ ที่ให้มา ในตัวอย่างนี้ เส้นทาง ‘DetailsScreen’ ถูกสร้างขึ้นโดยการแยก ‘data’ จาก ‘settings.arguments’ หากเส้นทางไม่ได้รับการจัดการใน ‘onGenerateRoute’ จะส่งคืนค่า ‘null’ และการโทรกลับ (callback) ‘onUnknownRoute’ จะถูกเรียกใช้ ซึ่งช่วยให้คุณแสดงหน้าจอที่กำหนดเองสำหรับเส้นทางที่ไม่รู้จัก เช่น หน้า “404 Not Found”

6. การเปลี่ยนเส้นทาง (Route Transitions)

การเปลี่ยนเส้นทางที่กำหนดเองสามารถปรับปรุงประสบการณ์ผู้ใช้โดยการเพิ่มภาพเคลื่อนไหวที่ดึงดูดสายตาเมื่อนำทางระหว่างหน้าจอต่างๆ หากต้องการสร้างการเปลี่ยนเส้นทางแบบกำหนดเอง คุณสามารถใช้คลาส ‘PageRouteBuilder’:

class FadeRouteTransition extends PageRouteBuilder {
  final Widget widget;

  FadeRouteTransition({required this.widget})
      : super(
          pageBuilder: (context, animation, secondaryAnimation) => widget,
          transitionsBuilder: (context, animation, secondaryAnimation, child) {
            return FadeTransition(
              opacity: animation,
              child: child,
            );
          },
        );
}

ในตัวอย่างนี้ คลาส ‘FadeRouteTransition’ ขยาย ‘PageRouteBuilder’ และกำหนดการเปลี่ยนเฟดแบบกำหนดเองโดยใช้วิดเจ็ต ‘FadeTransition’ ในการนำทางโดยใช้การเปลี่ยนแบบกำหนดเองนี้ เพียงแทนที่ ‘MaterialPageRoute’ ด้วย ‘FadeRouteTransition’:

Navigator.push(
  context,
  FadeRouteTransition(widget: DetailsScreen(data: 'Hello, Details!')),
);

การทำความเข้าใจการนำทางและการกำหนดเส้นทางเป็นสิ่งสำคัญสำหรับการทำแอพมือถือที่ใช้งานง่ายและเป็นมิตรกับผู้ใช้ ในบทความนี้ เราได้กล่าวถึงแนวคิดพื้นฐานของการนำทาง เส้นทาง ตั้งชื่อเส้นทาง การส่งผ่านข้อมูลระหว่างเส้นทาง การจัดการเส้นทางที่ไม่รู้จัก และการสร้างการเปลี่ยนเส้นทางแบบกำหนดเองในการทำแอพ Flutter เมื่อฝึกฝนทักษะเหล่านี้จนเชี่ยวชาญ คุณจะมีความพร้อมในการสร้างประสบการณ์ที่ราบรื่นและมีส่วนร่วมสำหรับผู้ใช้ในการทำแอพของคุณ

พัฒนาแอพด้วย Flutter

ตอนที่ 4 ทำแอพ Flutter : เลย์เอาต์ (Layout) และการออกแบบ UI
ตอนที่ 6 ทำแอพ Flutter : การจัดการสถานะ (State Management)