Reputation: 85
animation
I want the slide to move to the item I select. Please someone explain me to achieve the desired result.
Firstly, I am having a problem that I cannot align the icons with the slide in the center
.
error in layout in widget inspector in the row:
code:
/// bottom nav bar
Row(
children: [
SizedBox(
width: size.width,
height: size.height / 10,
child: Stack(
alignment: Alignment.center,
children: [
Container(
alignment: Alignment.center,
child: ClipRRect(
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 15,
sigmaY: 15,
),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).brightness == Brightness.light
? const Color.fromRGBO(184, 99, 99, 0.28)
: const Color.fromRGBO(255, 255, 255, 0.1),
border: Border(
top: BorderSide(
width: 1,
color:
Theme.of(context).brightness != Brightness.light
? Colors.white.withOpacity(0.2)
: Colors.pink.withOpacity(0.2),
),
),
),
),
),
),
),
/// slide
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
image: DecorationImage(
image: Theme.of(context).brightness == Brightness.light
? const AssetImage('assets/images/lgt_slide.png')
: const AssetImage('assets/images/drk_slide.png'),
fit: BoxFit.fill,
),
),
),
/// bar items
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
bnbItems('assets/icons/icn1.png', 0, 25.33),
bnbItems('assets/icons/icn2.png', 0, 32),
bnbItems('assets/icons/icn3.png', 0, 33.33),
bnbItems('assets/icons/icn4.png', 0, 17),
bnbItems('assets/icons/icn5.png', 0, 30),
],
),
],
),
),
],
);
}
Widget bnbItems(String image, int index, double height) {
return GestureDetector(
onTap: () => setState(() {
selectedIndex = index;
}),
child: Image.asset(
image,
height: height,
),
);
}
Upvotes: 0
Views: 1007
Reputation: 180
To me it looks like the size of the assets images might be different or they centre of the image might not be where it seems to be, you can check it by wrapping image in a coloured container to see it's size or just use Widget inspector tool.
I suggest you use presets like this https://gallery.flutter.dev/#/demo/bottom-navigation
Other option would be to use PositionedTransition on your Container, or SlideTransition. Here is an example https://api.flutter.dev/flutter/widgets/PositionedTransition-class.html
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'test_so',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
late final AnimationController _controller = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
@override
void dispose() {
_controller.dispose();
super.dispose();
}
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static const List<Widget> _widgetOptions = <Widget>[
Text(
'Index 0: Home',
style: optionStyle,
),
Text(
'Index 1: Business',
style: optionStyle,
),
Text(
'Index 2: School',
style: optionStyle,
),
];
void _onItemTapped(int index) {
_controller.animateTo(index / 2);
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: Stack(
alignment: Alignment.center,
children: [
BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
SlideTransition(
position: Tween<Offset>(
begin: const Offset(-1.0, 0.0),
end: const Offset(1.0, 0.0),
).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.linear,
),
),
child: Container(
height: 48,
width: MediaQuery.of(context).size.width / 3,
color: Colors.black26,
),
),
],
),
);
}
}
Upvotes: 1