Implementierung von CustomNavbar und benutzerdefinierte Menüschublade in FlutterAndroid

Forum für diejenigen, die für Android programmieren
Anonymous
 Implementierung von CustomNavbar und benutzerdefinierte Menüschublade in Flutter

Post by Anonymous »

Ich erstelle diese App -Benutzeroberfläche, ich bin gerade auf der Benutzeroberfläche der Startbildschirm und integriere die einfache Navigationsfunktion einer unteren Navigation und die Menüschublade. Als ich versuchte, die benutzerdefinierte Navigation zu fügen, die ich gemacht habe, ist es nicht klickbar. Ui < /p>

Code: Select all

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:waste_pal/widgets/menu-drawer.dart';
import 'package:waste_pal/widgets/bottom-nav.dart';
import 'package:waste_pal/scan.dart';
import 'package:waste_pal/rewards.dart';
import 'package:waste_pal/profile.dart';

class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("HomeScreen build() called");
return Scaffold(
endDrawer: CustomDrawer(),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(14.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset('assets/logo.png', height: 70),
Text(
"WASTE PAL",
style: TextStyle(
fontSize: 30,
fontFamily: 'Montserrat',
color: const Color.fromARGB(255, 35, 62, 46),
fontWeight: FontWeight.w900),
),
Builder(
builder: (context) => IconButton(
icon: Icon(Icons.menu,
size: 40, color: Color.fromARGB(255, 35, 62, 46)),
onPressed: () {
Scaffold.of(context)
.openEndDrawer();  // Open custom drawer
},
),
),
],
),

SizedBox(height: 20),

// Points Card
Stack(
clipBehavior: Clip.none,
children: [
Container(
width: double.infinity,
height: 100,
decoration: BoxDecoration(
color: Color(0xFF0A5D40),
borderRadius: BorderRadius.circular(20),
),
),
Positioned(
left: 30,
top: 20,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"50",
style: TextStyle(
color: Color(0xFFF5F8E4),
fontFamily: 'Montserrat',
fontSize: 70,
height: .7,
fontWeight: FontWeight.w900,
),
),
Text(
"POINTS",
style: TextStyle(
color: Color(0xFFF5F8E4),
fontFamily: 'Montserrat',
fontSize: 22,
fontWeight: FontWeight.normal,
),
),
],
),
),
Positioned(
right: -20,
top: -40,
child: Image.asset(
'assets/leaves.png',
height: 180,
),
),
],
),

SizedBox(height: 20),

Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Donation Info
Expanded(
flex: 1,
child: Container(
height: 200,
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color.fromARGB(255, 243, 250, 220),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(color: Colors.grey, blurRadius: 3)
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Where to donate plastic and recyclable waste?",
style: TextStyle(
fontWeight: FontWeight.w900,
fontFamily: 'Montserrat',
fontSize: 22,
color: const Color.fromARGB(255, 9, 93, 64),
),
),
Spacer(),
Text(
"18 January 2025 Waste Pal\n>click for more info",
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.normal,
fontSize: 12,
color: const Color.fromARGB(255, 9, 93, 64),
),
),
],
),
),
),

SizedBox(width: 10),

// Points Breakdown
Expanded(
flex: 1,
child: Stack(
clipBehavior: Clip.none,
children: [
// Background container with image
Container(
height: 200,
padding: EdgeInsets.all(10),
decoration:  BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/bg-leaves.png"),
fit: BoxFit.cover,
),
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(color: Colors.grey, blurRadius: 4)
],
),
),

// Positioned Points Boxes
Positioned(
top: 5,
left: 5,
right: 5,
child: _pointsBox("2", "BIODEGRADABLE BOTTLE"),
),
Positioned(
top: 50,
left: 5,
right: 5,
child: _pointsBox("5", "PLASTIC CONTAINERS"),
),
Positioned(
top: 95,
left: 5,
right: 5,
child: _pointsBox("2", "GLASS BOTTLES"),
),
Positioned(
top: 140,
left: 5,
right: 5,
child: _pointsBox("1", "OTHER RECYCLABLES"),
),

// Rewards Icon Below
Positioned(
bottom: -25,
right: -5,
child: Image.asset("assets/rewards.png", height: 60),
),
],
),
),
],
),

SizedBox(height: 20),

// Quiz Section
SizedBox(
width: double.infinity,
child: Stack(
clipBehavior: Clip.none,
children: [
// Quiz Container (Background Box)
Container(
width: double.infinity,
padding: EdgeInsets.fromLTRB(10, 5, 10, 5),
decoration: BoxDecoration(
color: Color.fromARGB(255, 118, 172, 139),
borderRadius: BorderRadius.circular(20),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
SizedBox(height: 50),
Text(
"Test your eco-smarts with\n our quick Waste Quiz!",
style: TextStyle(
color: const Color.fromARGB(255, 255, 255, 255),
fontFamily: 'Monserrat'),
),
SizedBox(height: 2),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor:
const Color.fromARGB(255, 56, 116, 66),
foregroundColor:
const Color.fromARGB(255, 255, 255, 255),
),
child: Text(
"TAKE A QUIZ",
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold),
),
),
],
),
),

// Floating Image (Above Container)
Positioned(
top: -30,
right: 150,
child: Transform.rotate(
angle: pi / 180 * -15,
child: Image.asset(
"assets/quiz-leaves.png",
height:  200,
),
),
),

// "Waste Quiz"  Text with Stroke Effect (Above Image)
Positioned(
top: 15,
left: 130,
child: Stack(
children: [
Text(
"Waste Quiz",
style: TextStyle(
fontSize: 40,
fontFamily: 'Montserrat',
fontWeight: FontWeight.w900,
foreground: Paint()
..style = PaintingStyle.stroke
..strokeWidth = 4
..color = Color.fromARGB(255, 255, 255, 255),
),
),
Text(
"Waste Quiz",
style: TextStyle(
fontSize: 40,
fontFamily: 'Montserrat',
fontWeight: FontWeight.w900,
color: Color.fromARGB(255, 9, 93, 64),
),
),
],
),
),
],
),
),

SizedBox(height: 20),

// Vouchers
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_voucherCard("20 PESOS LOAD"),
_voucherCard("50 PESOS LOAD"),
],
),
],
),
),
),

// Custom Bottom Navigation Bar
bottomNavigationBar: CustomNavBar(
selectedIndex: 0,
onItemTapped: (index) {},
),
);
}

Widget _voucherCard(String title) {
return Container(
padding: EdgeInsets.all(10),
width: 150,
decoration: BoxDecoration(
color: const Color.fromARGB(255, 243, 250, 220),
borderRadius: BorderRadius.circular(10),
boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 4)],
),
child: Column(
children: [
Image.asset("assets/voucher.png", height: 80),
SizedBox(height: 0),
Text(title,
style: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'Montserrat',
fontSize: 15,
color: const Color.fromARGB(255, 16, 127, 142))),
Text("CLAIM NOW",
style: TextStyle(
color: const Color.fromARGB(255, 16, 127, 142),
fontFamily: 'Montserrat',
fontSize: 10)),
],
),
);
}

Widget _pointsBox(String points, String description) {
return SizedBox(
width: 160,
height: 40,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 1),
decoration: BoxDecoration(
color: const Color.fromARGB(255, 243, 250, 220),
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: const Color.fromARGB(61, 131, 131, 131),
blurRadius: 2,
spreadRadius: 1,
),
],
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
points,
style: TextStyle(
fontSize: 20,
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
color: const Color.fromARGB(255, 16, 127, 142)),
),
SizedBox(width: 5),
Text(
"PTS",
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 10,
color: const Color.fromARGB(255, 16, 127, 142)),
),
SizedBox(width: 10),
Expanded(
child: Text(
"Earned for $description",
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.bold,
fontFamily:  'Montserrat',
color: const Color.fromARGB(255, 16, 127, 142)),
),
),
],
),
),
);
}
}

< /code>
Unten finden Sie die Navigationsleiste < /p>
import 'package:flutter/material.dart';

class CustomNavBar extends StatelessWidget {
final int selectedIndex;
final Function(int) onItemTapped; // Callback function

CustomNavBar({required this.selectedIndex, required this.onItemTapped});

@override
Widget build(BuildContext context) {
return Container(
height: 60,
margin: EdgeInsets.fromLTRB(10, 0, 10, 10),
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 5),
decoration: BoxDecoration(
color: Color(0xFF0E5B3B),
borderRadius: BorderRadius.circular(40),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildNavItem(Icons.home, "Home", 0),
_buildNavItem(Icons.camera_alt, "Scan", 1),
_buildNavItem(Icons.workspace_premium_outlined, "Rewards", 2),
_buildNavItem(Icons.person, "Profile", 3),
],
),
);
}

Widget _buildNavItem(IconData icon, String label, int index) {
bool isSelected = selectedIndex == index;

return GestureDetector(
onTap: () => onItemTapped(index), // Call parent function
child: AnimatedContainer(
duration: Duration(milliseconds: 200),
padding: EdgeInsets.symmetric(horizontal: isSelected ? 22 : 12, vertical: 10),
decoration: BoxDecoration(
color: isSelected ? Color(0xFF67B891) : Colors.transparent,
borderRadius: BorderRadius.circular(30),
),
child: Row(
children: [
Icon(icon, color: Colors.white),
if (isSelected)
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
label,
style: TextStyle(color: Colors.white, fontWeight: FontWeight.normal, fontFamily: 'Montserrat', fontSize: 12),
),
),
],
),
),
);
}
}
< /code>
Dies ist das Menü < /p>
import 'package:flutter/material.dart';

class CustomDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Drawer(
width: MediaQuery.of(context).size.width * 0.6,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
bottomLeft: Radius.circular(30),
),
),
backgroundColor: Color(0xFFBFD9C5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Close Button
Padding(
padding: const EdgeInsets.fromLTRB(20, 40, 20, 10),
child: Align(
alignment: Alignment.topLeft,
child: IconButton(
icon: Icon(Icons.close, size: 30, color: Colors.black),
onPressed: () => Navigator.of(context).pop(),
),
),
),

SizedBox(height: 30),

// Menu Items
Expanded(
child: ListView(
padding: EdgeInsets.zero,
children: [
_buildDrawerItem(Icons.home, "Home", context),
_buildDrawerItem(Icons.card_giftcard, "Redeem", context),
_buildDrawerItem(Icons.quiz, "Quizlet", context),
_buildDrawerItem(Icons.library_books, "WasteKnows", context),
_buildDrawerItem(Icons.settings, "Settings", context),
_buildDrawerItem(Icons.help_outline, "Helps &  FAQs", context),
],
),
),

// Log Out Button at the Bottom
Padding(
padding: const EdgeInsets.all(20.0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF2D694F),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
minimumSize: Size(double.infinity, 50),
),
onPressed: () {
// Handle logout action
},
child: Text(
"Log out",
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
),

SizedBox(height: 20),
],
),
);
}

// Helper method for creating menu items
Widget _buildDrawerItem(IconData icon, String title, BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 15.0), // Adjust spacing
child: GestureDetector(
onTap: () => Navigator.pop(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.center, // Center both icon and text
children: [
Icon(icon, color: Color.fromARGB(255, 9, 93, 64)), // Centered Icon
SizedBox(width: 10), // Space between icon and text
Text(
title,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
),
],
),
),
);
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post