Есть ли встроенный способ во Flutter, чтобы скрыть FloatingActionButton
в ListView
прокручивая вниз, а затем показывая его при прокрутке вверх?
Flutter - Скрытие FloatingActionButton
Ответ 1
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
ScrollController _hideButtonController;
void _incrementCounter() {
setState(() {
_counter++;
});
}
var _isVisible;
@override
initState(){
super.initState();
_isVisible = true;
_hideButtonController = new ScrollController();
_hideButtonController.addListener((){
if(_hideButtonController.position.userScrollDirection == ScrollDirection.reverse){
if(_isVisible == true) {
/* only set when the previous state is false
* Less widget rebuilds
*/
print("**** ${_isVisible} up"); //Move IO away from setState
setState((){
_isVisible = false;
});
}
} else {
if(_hideButtonController.position.userScrollDirection == ScrollDirection.forward){
if(_isVisible == false) {
/* only set when the previous state is false
* Less widget rebuilds
*/
print("**** ${_isVisible} down"); //Move IO away from setState
setState((){
_isVisible = true;
});
}
}
}});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new CustomScrollView(
controller: _hideButtonController,
shrinkWrap: true,
slivers: <Widget>[
new SliverPadding(
padding: const EdgeInsets.all(20.0),
sliver: new SliverList(
delegate: new SliverChildListDelegate(
<Widget>[
const Text('I\'m dedicating every day to you'),
const Text('Domestic life was never quite my style'),
const Text('When you smile, you knock me out, I fall apart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('And I thought I was so smart'),
const Text('I realize I am crazy'),
],
),
),
),
],
)
),
floatingActionButton: new Visibility(
visible: _isVisible,
child: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
),
),
);
}
}
Я извиняюсь, если не использовал просмотр списка, так как не знаю, как прокрутить просмотр списка. Я отвечу на другие части вашего вопроса.
Сначала вам нужно создать scrollcontroller, который будет прослушивать scrollPostion события
Если scrollcontroller удается найти направление прокрутки вперед или назад. Вы добавляете состояние, которое устанавливает состояние видимым.
Когда вы рисуете кнопку, вы оборачиваете ее в класс видимости. Вы устанавливаете видимый флаг, и виджет должен игнорировать входные команды.
Изменение: я не могу добавить ссылки на ScrollController, ScrollerPosition, ScrollDirection и Opacity. Я думаю, что вы можете искать его самостоятельно или кто-то еще редактировать в ссылках
Edit2: используйте CopsonRoad или используйте виджет видимости, если вы не хотите неокрашенный виджет в дереве макета
Edit3: в свете новичков, использующих код как есть, я бы обновил код, чтобы поощрять лучшие практики. Используйте видимость вместо непрозрачности. Удалить io из setState. протестировано на Flutter 1.5.4-hotfix.2
Ответ 2
Есть много способов передать это. Позвольте мне перечислить несколько здесь.
Вы можете использовать
Visibility
, чтобы скрыть/показать FAB.floatingActionButton: Visibility( child: FloatingActionButton(...), visible: false, // set it to false )
В Dart 2.2 вы можете использовать условие
if
, например:floatingActionButton: Column( children: <Widget>[ if (shouldShow) FloatingActionButton(...), // visible if showShould is true ], )
Вы можете использовать виджет
Opacity
.floatingActionButton: Opacity( opacity: shouldShow ? 1 : 0, // visible if showShould is true child: FloatingActionButton(...), )
Ответ 3
Вы можете использовать виджет Visibility
для обработки видимости дочернего виджета
образец:
floatingActionButton:
Visibility(visible: _visibilityFlag , child: _buildFAB(context)),
Ответ 4
Что мы должны делать, если listview находится внутри FutureBuilder.
Ответ 5
Другой очень хороший способ - AnimatedOpacity
AnimatedOpacity(
opacity: isEnabled ? 0.0 : 1.0,
duration: Duration(milliseconds: 1000),
child: FloatingActionButton(
onPressed: your_method,
tooltip: 'Increment',
child: new Icon(Icons.add),
),
)