#flutter
#трепетание
Вопрос:
Когда я создал макет ящика после Добавления ящика в документы экрана, все работает нормально. Однако у меня проблема, это значок меню.
В Android я настраиваю макет ящика с помощью DrawerToggle, и когда я открываю ящик, значок меню изменится на значок стрелки, а когда я закрываю ящик, значок стрелки изменится на значок меню.
В Flutter это работает не так, как указано выше.
Если вы понимаете мою проблему, пожалуйста, помогите мне. Я много искал, но не нашел решения. Итак, я хочу спросить всех. Большое вам спасибо.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final appTitle = 'Drawer Demo';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Center(child: Text('My Page!')),
drawer: Drawer(
// Add a ListView to the drawer. This ensures the user can scroll
// through the options in the Drawer if there isn't enough vertical
// space to fit everything.
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
],
),
),
);
}
}
Комментарии:
1. Почему вы хотите изменить значок ящика, поскольку при открытии ящика он скроет его. flutter.dev /изображения / кулинарная книга /drawer.png
2. В большинстве случаев то, что вы говорите, верно. Но иногда расположение ящика находится под значком меню и панелью инструментов, например: i.stack.imgur.com/hK4mD.png
3. Если это так, проверьте мой ответ
Ответ №1:
Используйте, StateFulWidget
чтобы вы могли получить доступ setState
к способу изменения значка
В вашем state
классе
Определите Global Key
final GlobalKey<ScaffoldState> _key = GlobalKey();
Определите, boolean
чтобы проверить, Drawer
открыто ли.
bool _isDrawerOpen = false;
Добавьте их в свой state
класс
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Title'),
leading: IconButton(
icon: _isDrawerOpen ? Icon(Icons.menu) : Icon(Icons.arrow_back),
onPressed: onPressed,
),
),
drawer: WillPopScope(child: Drawer(), onWillPop: onPop),
body: //body
key: this._key,
);
}
void onPressed() {
if (!_isDrawerOpen) {
this._key.currentState.openDrawer();
} else {
Navigator.pop(context);
}
setState(() {
_isDrawerOpen = !_isDrawerOpen;
});
}
void onPop() {
if (_isDrawerOpen) {
setState(() {
_isDrawerOpen = false;
});
}
Navigator.pop(context);
}
Комментарии:
1. Я понимаю вашу идею. Это работало довольно хорошо, хотя были некоторые незначительные ошибки. И вы, и код @ android сработали для меня. Большое вам спасибо.
Ответ №2:
Чтобы изменить значок гамбургера при открытом ящике, а также отобразить ящик под панелью приложений:
Я объявил «МЕТОД 1» и «МЕТОД 2» в своем коде, которые указаны в комментариях.
«МЕТОД 1» позволяет открыть ящик и изменить значок с обратным вызовом контроллера ящика.
«МЕТОД 2» позволяет открывать ящик, когда мы нажимаем значок гамбургера, Проблема в том, что мы не можем щелкнуть значок гамбургера при использовании контроллера ящика.
import 'package:flutter/material.dart';
class MyNavDrawerController extends StatefulWidget {
createState() {
return StateKeeper();
}
}
class StateKeeper extends State<MyNavDrawerController> {
// Declare a new variable which will increment on FAB tap
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final appBarColor = const Color(0xFFd2527f);
var myIcon = new Icon(Icons.list);
DrawerCallback drawerCallback(bool status) {
Fluttertoast.showToast(
msg: "Drawer " status.toString(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: appBarColor,
textColor: Colors.white,
fontSize: 14.0);
setState(() {
setMenuIcon(status);
});
}
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
primary: true,
appBar: AppBar(
title: Text("Parent Scaffold"),
leading: new IconButton(icon: myIcon,
onPressed:(){
_scaffoldKey.currentState.openDrawer();
}
)
),
// METHOD 1
/*body: DrawerController(
child: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Andy Rubin'),
decoration: BoxDecoration(color: Colors.blue),
),
ListTile(
title: Text('Home'),
onTap: () {
setState(() {
Navigator.pop(context);
});
},
),
ListTile(
title: Text('About us'),
onTap: () {
Navigator.pop(context);
Fluttertoast.showToast(
msg: "About us clicked! :)",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
},
),
ListTile(
title: Text('Notifications'),
onTap: () {
Navigator.pop(context);
Fluttertoast.showToast(
msg: "Notifications clicked! :)",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.blue,
textColor: Colors.white,
fontSize: 18.0);
},
)
],
),
),
alignment: DrawerAlignment.start, drawerCallback: drawerCallback
),*/
// METHOD 2
/*body: Scaffold(
key: _scaffoldKey,
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Andy Rubin'),
decoration: BoxDecoration(color: Colors.blue),
),
ListTile(
title: Text('Home'),
onTap: () {
Fluttertoast.showToast(
msg: "Home clicked! :)",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: appBarColor,
textColor: Colors.white,
fontSize: 14.0);
setState(() {
Navigator.pop(context);
});
},
),
ListTile(
title: Text('About us'),
onTap: () {
Navigator.pop(context);
Fluttertoast.showToast(
msg: "About us clicked! :)",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
},
),
ListTile(
title: Text('Notifications'),
onTap: () {
Navigator.pop(context);
Fluttertoast.showToast(
msg: "Notifications clicked! :)",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.blue,
textColor: Colors.white,
fontSize: 18.0);
},
)
],
),
),
)*/
);
}
void setMenuIcon(bool isDrawerOpen){
if(isDrawerOpen){
myIcon = new Icon(Icons.list);
}else{
myIcon = new Icon(Icons.arrow_back);
}
}
}
Комментарии:
1. Ваше объяснение отличное, подробное. МЕТОД 1 сработал нормально, МЕТОД 2 выдает небольшую ошибку: _scaffoldKey. И вы, и код @Mangaldeep Pannu сработали для меня. Большое вам спасибо.
Ответ №3:
Ниже я прикрепляю фрагмент моего кода, который, на мой взгляд, является самым простым способом создать пользовательский значок гамбургера. Основная часть кода заключается в использовании ведущего:!
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0.0,
leading: Builder(
builder: (context) => IconButton(
icon: Icon(
Icons.sort,
color: Colors.black54,
),
onPressed: () => Scaffold.of(context).openDrawer(),
tooltip:
MaterialLocalizations.of(context).openAppDrawerTooltip,
)),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text('App'),
),
ListTile(
title: Text('Item 1'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),)