Flutter PageTransitionSwitcher का उपयोग करके टैब की स्थिति नहीं रख सकता है
मैं एनिमेशन पैकेज के साथ संघर्ष कर रहा हूं और मैं बॉटनवैनरिगेशन के साथ एनीमेशन का उपयोग करना चाहता हूं। एनीमेशन के बिना, मैं IndexedStack का उपयोग करके अपने राज्य को बचा सकता हूं। यदि मैं PageTransitionSwitcher के अंदर IndexedStack लपेटता हूं तो यह काम नहीं करता है। विशेष रूप से:
- एनिमेशन नहीं दिखा रहे हैं लेकिन राज्य रखा गया है
- यदि मैं अपने IndexedStack की प्रमुख संपत्ति का उपयोग करता हूं, तो एनिमेशन दिखा रहे हैं, लेकिन राज्य काम नहीं कर रहा है।
मेरे द्वारा यह कैसे किया जा सकता है? मुझे नहीं पता कि चाबियाँ कैसे सेट करें। आपका बहुत बहुत धन्यवाद!!
class MainScreen extends StatefulWidget {
static String id = 'loading_screen';
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
int _selectedPage = 0;
List<Widget> pageList = List<Widget>();
@override
void initState() {
pageList.add(PrimoTab());
pageList.add(SecondoTab());
pageList.add(TerzoTab());
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bottom tab'),
),
body: PageTransitionSwitcher(
transitionBuilder: (child, primaryAnimation, secondaryAnimation) {
return SharedAxisTransition(
animation: primaryAnimation,
secondaryAnimation: secondaryAnimation,
child: child,
transitionType: SharedAxisTransitionType.horizontal,
);
},
child: IndexedStack(
index: _selectedPage,
children: pageList,
//key: ValueKey<int>(_selectedPage), NOT WORKING
),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.directions_car),
label: 'First Page',
),
BottomNavigationBarItem(
icon: Icon(Icons.airplanemode_active),
label: 'Second Page',
),
BottomNavigationBarItem(
icon: Icon(Icons.directions_bike),
label: 'Third Page',
),
],
currentIndex: _selectedPage,
selectedItemColor: Colors.lightGreen,
unselectedItemColor: Colors.lightBlueAccent,
onTap: _onItemTapped,
),
);
}
void _onItemTapped(int index) {
setState(() {
_selectedPage = index;
});
}
}
प्रत्येक टैब दो टेक्स्ट विजेट, एक बटन और एक टेक्स्ट काउंटर (प्रत्येक टैब की स्थिति का परीक्षण करने के लिए) के साथ एक कॉलम है:
class PrimoTab extends StatefulWidget {
@override
_PrimoTabState createState() => _PrimoTabState();
}
class _PrimoTabState extends State<PrimoTab> {
int cont = -1;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'TAB 1 - TEXT 1',
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'TAB 1 - TEXT 2',
),
),
FlatButton(
onPressed: () {
setState(() {
cont++;
});
},
child: Text("CLICK"),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Valore contatore $cont',
),
),
],
),
);
}
}
अद्यतन 1: बस का उपयोग कर
pageList[_selectedPage],
के बजाय
IndexedStack(
...
)
लेकिन काम नहीं कर रहा है (एनिमेशन ठीक है लेकिन राज्य नहीं रखा गया है)
समाधान के साथ 2 अद्यतन (main.dart):
void main() {
runApp(
MaterialApp(
home: MainScreen(),
),
);
}
class MainScreen extends StatefulWidget {
static String id = 'loading_screen';
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
int _selectedPage = 0;
List<Widget> pageList = List<Widget>();
@override
void initState() {
pageList.add(PrimoTab());
pageList.add(SecondoTab());
pageList.add(TerzoTab());
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bottom tab'),
),
body: AnimatedIndexedStack(
index: _selectedPage,
children: pageList,
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.directions_car),
label: 'First Page',
),
BottomNavigationBarItem(
icon: Icon(Icons.airplanemode_active),
label: 'Second Page',
),
BottomNavigationBarItem(
icon: Icon(Icons.directions_bike),
label: 'Third Page',
),
],
currentIndex: _selectedPage,
selectedItemColor: Colors.lightGreen,
unselectedItemColor: Colors.lightBlueAccent,
onTap: _onItemTapped,
),
);
}
void _onItemTapped(int index) {
setState(() {
_selectedPage = index;
});
}
}
class AnimatedIndexedStack extends StatefulWidget {
final int index;
final List<Widget> children;
const AnimatedIndexedStack({
Key key,
this.index,
this.children,
}) : super(key: key);
@override
_AnimatedIndexedStackState createState() => _AnimatedIndexedStackState();
}
class _AnimatedIndexedStackState extends State<AnimatedIndexedStack>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<double> _animation;
int _index;
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 150),
);
_animation = Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.ease,
),
);
_index = widget.index;
_controller.forward();
super.initState();
}
@override
void didUpdateWidget(AnimatedIndexedStack oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.index != _index) {
_controller.reverse().then((_) {
setState(() => _index = widget.index);
_controller.forward();
});
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Opacity(
opacity: _controller.value,
child: Transform.scale(
scale: 1.015 - (_controller.value * 0.015),
child: child,
),
);
},
child: IndexedStack(
index: _index,
children: widget.children,
),
);
}
}
जवाब
आपकी स्थिति को ठीक करने के कुछ तरीके हैं। उनमें से कोई भी पूरी तरह से सरल नहीं है और पहले से ही यहाँ और यहाँ बहुत चर्चा है , IndexedStack
साथ विलय करने की कोशिश कर रहा है PageTransitionSwitcher
। अब तक कोई समाधान नहीं मैंने देखा।
मैं इसे प्राप्त करने के लिए संभावित तरीके एकत्र करता हूं:
राज्य को कहीं और स्टोर करें और बच्चे को पास करें। मैंने नहीं देखा है कि कोई भी विधि
PageTransitionSwitcher
बाल विजेट के पुनर्निर्माण से रोक सकती है । यदि आप चाइल्ड विजेट पुनर्निर्माण नहीं करते हैं , तो ऐसा करने के लिए यह सबसे सीधा फॉरवर्ड तरीका हो सकता है।IndexedStack
एनीमेशन के साथ कस्टम का उपयोग करें । यह और यह पसंद है । यह IndexStack में इस सुविधा के साथ अच्छी तरह से काम करता है कि बच्चे पुनर्निर्माण नहीं करेंगे, लेकिन एनीमेशन उतना अच्छा नहीं हैPageTransitionSwitcher
और यह केवल एक बार में 1 विजेट दिखा सकता है।