تعلّم كيف تجعل BottomNavigationBar يظهر في كل الشاشات في تطبيقات Flutter
يعد Flutter أحد أكثر أطر العمل شيوعًا لبناء تطبيقات الهاتف المحمول، وإحدى الميزات شائعة الاستخدام هي استخدام BottomNavigationBar للتنقل بين الشاشات المختلفة داخل التطبيق. في هذه المقالة سوف نقوم بحل مشكلة شائعة يواجهها العديد من المطورين عند التعامل مع BottomNavigationBar، وهي كيفية جعل BottomNavigationBar يظهر في جميع الشاشات، حتى لو لم تكن هذه الشاشات جزءًا من علامة التبويب الرئيسية، وكيفية الاحتفاظ بالحالة من BottomNavigationBar في كل خيار عند التنقل بين البطاقات.
فقدان حالة علامة التبويب والتنقل بين الشاشات
المشكلة التي يواجهها العديد من المطورين هي أنه عند الانتقال إلى شاشة أخرى في أي علامة تبويب، يختفي BottomNavigationBar نظرًا لوجود متصفح واحد فقط في التطبيق. وهذا يعني أن التطبيق يعرض فقط حالة شاشة واحدة ويحافظ عليها في أي وقت، وعندما تنتقل إلى شاشة جديدة في علامة تبويب، يتم فقدان الحالة السابقة.
ما هو السبب الرئيسي وراء هذه المشكلة؟
السبب الرئيسي وراء هذه المشكلة هو استخدام Navigator واحد في التطبيق. يعرض Navigator شاشة واحدة فقط في كل مرة، وعندما تنتقل إلى شاشة جديدة، يتم تحديث حالة الشاشة الحالية ويتم فقدان الشاشة السابقة.
استخدم Multiple Navigators
لحل هذه المشكلة، نحتاج إلى استخدام متصفحات متعددة، أي أن كل علامة تبويب في التطبيق لها متصفح خاص بها. يتيح ذلك لكل علامة تبويب الاحتفاظ بحالتها حتى بعد نقلها إلى شاشات أخرى في التطبيق.
كيف يمكننا تنفيذ فكرة تعدد المتصفحات في Flutter؟
الخطوة الأولى هي إنشاء قائمة GlobalKeys بحيث يكون لكل علامة تبويب في التطبيق متصفح منفصل، لتتمكن من تخزين حالة كل علامة تبويب على حدة.
List<GlobalKey<NavigatorState>> navigatorKeys = [
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
];ما فائدة استخدام GlobalKeys هنا؟
List<Widget> _buildScreens() {
return [
Navigator(
key: navigatorKeys[0],
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(
builder: (context) => Screen1(), // شاشة الـ Tab الأول
);
},
),
Navigator(
key: navigatorKeys[1],
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(
builder: (context) => Screen2(), // شاشة الـ Tab الثاني
);
},
),
Navigator(
key: navigatorKeys[2],
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(
builder: (context) => Screen3(), // شاشة الـ Tab الثالث
);
},
),
];
}لماذا نستخدم onGenerateRoute؟
استخدم IndexedStack مع BottomNavigationBar
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0; // الفهرس الذي يمثل الـ Tab النشط
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _selectedIndex,
children: _buildScreens(), // بناء الشاشات الخاصة بكل Tab
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
),
);
}
}