如何解决CustomScrollView抖动内的FutureBuilder <dynamic>
嗨,我想设计一个页面,该页面应垂直滚动并具有GridView.builder。我正在服务器上加载数据,并且如果数据处于共享首选项中,那么我将从共享首选项中获取它。对于GridView.builder,我正在使用FutureBuilder加载数据。但是下面我得到的错误是错误
'owner._debugCurrentBuildTarget == this':不正确
下面是代码。
void main() {
WidgetsFlutterBinding.ensureInitialized();
// Initialize without device test ids
Admob.initialize();
// Add a list of test ids.
// Admob.initialize(testDeviceIds: ['YOUR DEVICE ID']);
runApp(FirstScreen());
}
class FirstScreen extends StatefulWidget {
@override
_CrosspromoPageState createState() => _CrosspromoPageState();
}
class _CrosspromoPageState extends State<FirstScreen> {
AdmobInterstitial interstitialAd;
List<CrosspromotionPojo> crosspromoobject = List();
@override
void initState() {
// TODO: implement initState
super.initState();
// getCrosspromodata();
// loadcrossPromodata();
interstitialAd = AdmobInterstitial(
adUnitId: getInterstitialAdUnitId(),listener: (AdmobAdEvent event,Map<String,dynamic> args) {
if (event == AdmobAdEvent.closed) interstitialAd.load();
},);
interstitialAd.load();
}
String getInterstitialAdUnitId() {
if (Platform.isIOS) {
return 'ca-app-pub-3940256099942544/4411468910';
} else if (Platform.isAndroid) {
return 'ca-app-pub-3940256099942544/1033173712';
}
return null;
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
SizeConfig().init(context);
return Scaffold(
body: Container(
child: CustomScrollView(
slivers: <Widget>[
new Image.asset('assets/images/bg_half_image.jpg'),new Align(
alignment: Alignment.topCenter,child: new Container(
margin: EdgeInsets.fromLTRB(0,55,0),width: 150,height: 150,child: Image.asset('assets/images/logo.png'),)),child: InkWell(
onTap: () async {
if (await interstitialAd.isLoaded) {
interstitialAd.show();
}
int val = await DatabaseHelper.instance.queryRowCount();
if (val == 0) {
DatabaseHelper.instance.insertExcdaydata();
DatabaseHelper.instance.insertExcdaydatainapp();
} else
Navigator.pop(context,true);
{
Navigator.push(
context,MaterialPageRoute(
builder: (context) => BannerPage(),),);
}
},child: new Container(
width: 150,margin: EdgeInsets.fromLTRB(0,200,//padding: EdgeInsets.fromLTRB(4,4,4),child: new Image.asset('assets/images/start.png'),))),new Container(
alignment: Alignment.topCenter,margin: EdgeInsets.only(
left: 0,right: 0,top: SizeConfig.screenHeight / 1.8,bottom: 0),child: Text("TRY OUR NEW APPS",style: TextStyle(
color: Colors.black,fontWeight: FontWeight.bold,fontSize: 20)),new FutureBuilder<dynamic>(
future: getCrosspromodata(),builder:
(BuildContext context,AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: Text('Please wait its loading...'));
} else {
return Container(
margin: EdgeInsets.only(
left: 0,top: SizeConfig.screenHeight / 1.6,child: Align(
child: GridView.builder(
itemCount: crosspromoobject.length,itemBuilder: (context,index) => GestureDetector(
onTap: () => tapped(index),child: Container(
child: new Card(
elevation: 2,child: Column(
children: <Widget>[
new Container(
child: CachedNetworkImage(
imageUrl: crosspromoobject[index].appUrl,placeholder: (context,url) =>
CircularProgressIndicator(),errorWidget: (context,url,error) =>
Icon(Icons.error),new Container(
alignment:
AlignmentDirectional.centerStart,child: Text(
crosspromoobject[index].app_name,style: TextStyle(
color: Colors.black,fontSize: 15),))
],gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,mainAxisSpacing: 30,crossAxisSpacing: 15,childAspectRatio:
MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.1),);
}
})
],);
/*return Scaffold(
body: Scaffold(
body: Stack(
children: [
new Image.asset('assets/images/bg_half_image.jpg'),new Align(
alignment: Alignment.topCenter,child: new Container(
margin: EdgeInsets.fromLTRB(0,child: InkWell(
onTap: () async {
if (await interstitialAd.isLoaded) {
interstitialAd.show();
}
int val = await DatabaseHelper.instance.queryRowCount();
if (val == 0) {
DatabaseHelper.instance.insertExcdaydata();
DatabaseHelper.instance.insertExcdaydatainapp();
} else
Navigator.pop(context,true);
{
Navigator.push(
context,MaterialPageRoute(
builder: (context) => BannerPage(),);
}
},child: new Container(
width: 150,new Container(
alignment: Alignment.topCenter,margin: EdgeInsets.only(
left: 0,style: TextStyle(
color: Colors.black,new FutureBuilder<dynamic>(
future: getCrosspromodata(),builder: (BuildContext context,AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: Text('Please wait its loading...'));
} else {
return Container(
margin: EdgeInsets.only(
left: 0,child: Align(
child: GridView.builder(
itemCount: crosspromoobject.length,index) => GestureDetector(
onTap: () => tapped(index),child: Container(
child: new Card(
elevation: 2,child: Column(
children: <Widget>[
new Container(
child: CachedNetworkImage(
imageUrl: crosspromoobject[index].appUrl,url) =>
CircularProgressIndicator(),error) =>
Icon(Icons.error),new Container(
alignment: AlignmentDirectional.centerStart,child: Text(
crosspromoobject[index].app_name,style: TextStyle(
color: Colors.black,))
],gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.1),);
}
})
],)))*/
}
Future<dynamic> loadcrossPromodata() async {
SharedPreferences pref = await SharedPreferences.getInstance();
List<dynamic> tagObjsJson =
(json.decode(pref.getString('userData')) ?? List<dynamic>());
crosspromoobject = tagObjsJson
.map((tagJson) => CrosspromotionPojo.fromJson(tagJson))
.toList();
return tagObjsJson;
}
Future<dynamic> getCrosspromodata() async {
List<dynamic> tagObjsJson;
SharedPreferences pref = await SharedPreferences.getInstance();
try {
Response<Map> versionresponse = await Dio().get(
"https://videomergerapp.com/mobilestores/https/cross_promo_photoapps/verison.json");
Map arrayObjresponse = versionresponse.data;
int version = arrayObjresponse['healthw_version'];
int localversion = pref.getInt('local_version') ?? 0;
if (version > localversion) {
Response<Map> response = await Dio().get(
"https://videomergerapp.com/mobilestores/https/cross_promo_fitness/cross_promo_health_fitness_firstscreen.json");
String arrayObjsText = response.toString();
tagObjsJson = jsonDecode(arrayObjsText)['item_array'] as List;
crosspromoobject = tagObjsJson
.map((tagJson) => CrosspromotionPojo.fromJson(tagJson))
.toList();
savePojo(tagObjsJson);
pref.setInt('local_version',version);
return tagObjsJson;
} else {
loadcrossPromodata();
}
} catch (e) {
print(e);
}
}
Future<void> savePojo(List<dynamic> crosspromoobject) async {
SharedPreferences pref = await SharedPreferences.getInstance();
pref.setString('userData',json.encode(crosspromoobject));
print(crosspromoobject);
}
void tapped(int index) {
Fluttertoast.showToast(
msg: crosspromoobject[index].app_name,toastLength: Toast.LENGTH_SHORT,gravity: ToastGravity.CENTER,timeInSecForIosWeb: 1,backgroundColor: Colors.red,textColor: Colors.white,fontSize: 16.0);
}
}
解决方法
尝试将GridView
的属性shrinkWrap
设置为true
。
GridView.builder(
shrinkWrap: true,//...
)
,
因此,我通过在CustomScrollView中获取SliverList和SliverChildListDelegate并将其高度设置为FutureBuilder内部的容器的高度来做到这一点:SizeConfig.screenHeight / 1.10,下面是完整的代码。
void main() {
WidgetsFlutterBinding.ensureInitialized();
// Initialize without device test ids
Admob.initialize();
// Add a list of test ids.
// Admob.initialize(testDeviceIds: ['YOUR DEVICE ID']);
runApp(FirstScreen());
}
class FirstScreen extends StatefulWidget {
@override
_CrosspromoPageState createState() => _CrosspromoPageState();
}
class _CrosspromoPageState extends State<FirstScreen> {
AdmobInterstitial interstitialAd;
List<CrosspromotionPojo> crosspromoobject = List();
@override
void initState() {
// TODO: implement initState
super.initState();
// getCrosspromodata();
// loadcrossPromodata();
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
SizeConfig().init(context);
return Scaffold(
body: Container(
child: CustomScrollView(slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate(
[
Stack(
children: [
new Image.asset('assets/images/bg_half_image.jpg'),new Align(
alignment: Alignment.topCenter,child: new Container(
margin: EdgeInsets.fromLTRB(0,55,0),width: 150,height: 150,child: Image.asset('assets/images/logo.png'),)),child: InkWell(
onTap: () async {
if (await interstitialAd.isLoaded) {
interstitialAd.show();
}
int val = await DatabaseHelper.instance.queryRowCount();
if (val == 0) {
DatabaseHelper.instance.insertExcdaydata();
DatabaseHelper.instance.insertExcdaydatainapp();
} else
Navigator.pop(context,true);
{
Navigator.push(
context,MaterialPageRoute(
builder: (context) => BannerPage(),),);
}
},child: new Container(
width: 150,margin: EdgeInsets.fromLTRB(0,200,//padding: EdgeInsets.fromLTRB(4,4,4),child: new Image.asset('assets/images/start.png'),)))
],new SizedBox(
height: 50,width: double.infinity,child: Container(
margin: EdgeInsets.fromLTRB(0,15,color: Colors.white,child: Text(
"TRY OUR NEW APPS",textAlign: TextAlign.center,style: TextStyle(
color: Colors.black,fontWeight: FontWeight.bold,fontSize: 20),new FutureBuilder<dynamic>(
future: getCrosspromodata(),builder: (BuildContext context,AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: Text('Please wait its loading...'));
} else {
return Container(
height: SizeConfig.screenHeight / 1.10,margin:
EdgeInsets.only(left: 0,right: 0,top: 0,bottom: 0),child: Align(
child: GridView.builder(
itemCount: crosspromoobject.length,itemBuilder: (context,index) => GestureDetector(
onTap: () => tapped(index),child: Container(
child: new Card(
elevation: 2,child: Column(
children: <Widget>[
new Container(
child: CachedNetworkImage(
imageUrl: crosspromoobject[index].appUrl,placeholder: (context,url) =>
CircularProgressIndicator(),errorWidget: (context,url,error) =>
Icon(Icons.error),new Container(
alignment: AlignmentDirectional.centerStart,child: Text(
crosspromoobject[index].app_name,style: TextStyle(
color: Colors.black,fontSize: 15),))
],gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,mainAxisSpacing: 30,crossAxisSpacing: 15,childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.1),);
}
})
],]))
// This trailing comma makes auto-formatting nicer for build methods.
);
}
Future<String> loadcrossPromodata() async {
SharedPreferences pref = await SharedPreferences.getInstance();
List<dynamic> tagObjsJson =
(json.decode(pref.getString('userData')) ?? List<dynamic>());
crosspromoobject = tagObjsJson
.map((tagJson) => CrosspromotionPojo.fromJson(tagJson))
.toList();
}
Future<dynamic> getCrosspromodata() async {
List<dynamic> tagObjsJson;
SharedPreferences pref = await SharedPreferences.getInstance();
try {
Response<Map> versionresponse = await Dio().get(
"https://videomergerapp.com/mobilestores/https/cross_promo_photoapps/verison.json");
Map arrayObjresponse = versionresponse.data;
int version = arrayObjresponse['healthw_version'];
int localversion = pref.getInt('local_version') ?? 0;
if (version > localversion) {
Response<Map> response = await Dio().get(
"https://videomergerapp.com/mobilestores/https/cross_promo_fitness/cross_promo_health_fitness_firstscreen.json");
String arrayObjsText = response.toString();
tagObjsJson = jsonDecode(arrayObjsText)['item_array'] as List;
crosspromoobject = tagObjsJson
.map((tagJson) => CrosspromotionPojo.fromJson(tagJson))
.toList();
savePojo(tagObjsJson);
pref.setInt('local_version',version);
return tagObjsJson;
} else {
loadcrossPromodata();
}
} catch (e) {
print(e);
}
}
Future<void> savePojo(List<dynamic> crosspromoobject) async {
SharedPreferences pref = await SharedPreferences.getInstance();
pref.setString('userData',json.encode(crosspromoobject));
print(crosspromoobject);
}
void tapped(int index) {
Fluttertoast.showToast(
msg: crosspromoobject[index].app_name,toastLength: Toast.LENGTH_SHORT,gravity: ToastGravity.CENTER,timeInSecForIosWeb: 1,backgroundColor: Colors.red,textColor: Colors.white,fontSize: 16.0);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。