-
-
Save ianldgs/794884d8837b83fd9c64e06d9b90af4e to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart'; | |
void main() => runApp(new MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return new MaterialApp( | |
title: 'Flutter Demo', | |
theme: new ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: new MyHomePage(title: 'My Flutter Pad'), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
MyHomePage({Key key, this.title}) : super(key: key); | |
final String title; | |
@override | |
_MyHomePageState createState() => new _MyHomePageState(); | |
} | |
const kExpandedHeight = 300.0; | |
class _MyHomePageState extends State<MyHomePage> { | |
ScrollController _scrollController; | |
@override | |
void initState() { | |
super.initState(); | |
_scrollController = ScrollController() | |
..addListener(() => setState(() {})); | |
} | |
bool get _showTitle { | |
return _scrollController.hasClients | |
&& _scrollController.offset > kExpandedHeight - kToolbarHeight; | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: CustomScrollView( | |
controller: _scrollController, | |
slivers: <Widget>[ | |
SliverAppBar( | |
pinned: true, | |
leading: IconButton(icon: Icon(Icons.menu), onPressed: () {},), | |
expandedHeight: kExpandedHeight, | |
title: _showTitle ? Text('_SliverAppBar') : null, | |
flexibleSpace: _showTitle ? null : FlexibleSpaceBar( | |
title: new Column( | |
mainAxisAlignment: MainAxisAlignment.end, | |
children: <Widget>[ | |
Text('_SliverAppBar'), | |
Text('subtitle'), | |
], | |
), | |
background: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Text('Info'), | |
], | |
), | |
), | |
), | |
SliverList( | |
delegate: SliverChildListDelegate(List<Text>.generate(100, (int i) { | |
return Text("List item $i"); | |
})), | |
), | |
] | |
), | |
); | |
} | |
} |
Not sure about performance (would have to be measured), but it's definitely not recommended by the community to call an empty setState
.
I've extracted this piece of code from a widget of mine a long time ago, so I could have a reference whenever I needed. However, the widget in question was also doing a parallax and I was just getting started with flutter.
Your example is really better and I recommend anyone with a use case like this to use it.
I already try this,Anyway nice demo.
But i have some question, Why everytime i scrolled my listview always refresh. I assume this script make my listview always refresh every scrolled. And make my app very slow.
_scrollController = ScrollController()
..addListener(() => setState(() {}));
}
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_news/api/Api_news.dart';
import 'package:flutter_news/pages/display_json/FetchNewsByWartawan.dart';
import 'package:flutter_news/pages/reusableWidget/DataNotFound.dart';
import 'package:flutter_news/pages/reusableWidget/LoadingIndicator.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class WartawanDetail extends StatefulWidget {
final int idWartawan;
final String gambarWartawan;
final String namaWartawan;
final int jumlahBerita;
WartawanDetail({
this.idWartawan,
this.gambarWartawan,
this.namaWartawan,
this.jumlahBerita,
});
@override
_WartawanDetailState createState() => _WartawanDetailState();
}
class _WartawanDetailState extends State<WartawanDetail> {
ScrollController _scrollController;
ApiHelper api = ApiHelper();
@override
void initState() {
super.initState();
_scrollController = ScrollController()
..addListener(() => setState(() {
print("${_scrollController.offset}");
}));
}
bool get _changeColor {
return _scrollController.hasClients &&
_scrollController.offset > (250 - kToolbarHeight);
}
@override
Widget build(BuildContext context) {
return SafeArea(
top: true,
child: Scaffold(
body: CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
SliverAppBar(
floating: false,
pinned: true,
expandedHeight: ScreenUtil.getInstance().setHeight(250),
leading: Container(
child: IconButton(
icon: Icon(
Icons.arrow_back,
color: _changeColor ? Colors.blue : Colors.black,
),
onPressed: () => Navigator.pop(context),
),
),
flexibleSpace: FlexibleSpaceBar(
title: Container(
child: Text(widget.namaWartawan),
),
background: Container(
child: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl:
"${Urls.BASE_API_IMAGE}/wartawan/${widget.gambarWartawan}",
),
),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.more_horiz),
onPressed: () => "",
),
],
),
SliverFixedExtentList(
itemExtent: MediaQuery.of(context).size.height,
delegate: SliverChildListDelegate(
[
Container(
padding: EdgeInsets.all(8),
child: FutureBuilder(
future: api.getBeritaByWartawan(widget.idWartawan),
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
case ConnectionState.active:
return LoadingIndicator();
break;
default:
if (!snapshot.hasData) {
return DataNotFound();
} else {
return ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return FetchNewsByWartawan(
idBerita: snapshot.data[index].idBerita,
judulBerita:
snapshot.data[index].judulBerita,
isiBerita: snapshot.data[index].isiBerita,
namaKategori:
snapshot.data[index].namaKategori,
namaWartawan:
snapshot.data[index].namaWartawan,
tanggalBerita:
snapshot.data[index].tanggalBerita,
gambarBerita:
snapshot.data[index].gambarBerita,
);
},
);
}
}
},
),
),
],
),
)
],
),
),
);
}
}
@zgramming you will maybe have better luck following @fattiger00's gist. Your widget just needs to rebuild when the colour will in fact change. Maybe putting the scroll logic and list logic in separate widgets would be wise.
Excellent demo. but using
..addListener(() => setState(() {}));
Does do like this will have bad effect on performance?Making
_showTitle
as a property, adding a condition to call setState method, will it be better?like this The way I thought