How do I use a builder function? - flutter
Asked Answered
F

1

6

I have asked a question named 'How to inject a Widget into a custom child Widget and use the child Widgets iteration index?' I already got an answer but there is a problem.

The answer said that I should:

"Instead of passing a Widget to your custom AppList you could pass a builder function that returns a Widget and takes the parameters as required, e.g. the index and whatever configuration is required. Something like the following:

Function definition:

typedef Widget MyListTileBuilder(String tileText);

then change the following:

final Widget child;

to

final MyListTileBuilder childBuilder;

of course you need to implement your builder method in Example Class:

Widget MyListTileBuilderImplementation (int index) {
  return ListTile ( 
                title: Text(installedApps[index]["app_name"]) //this is the text
              ),
}

when you build AppList inside example class you pass the method

AppList (
              childBuilder: MyListTileBuilderImplementation 
)

and finally inside AppList you call the builder, instead of adding child widget" :

itemBuilder: (context, index) {
  return childBuilder(index); //This is where the ListTile will go. 
},

So, I tried to edit my code. But for some reason it was not working. I think that I'm doing it wrong. Does anybody know how to solve this problem? (It would be very very helpful if you could edit my full code.)

Full Code:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'dart:async';
import 'dart:io';

import 'package:flutter_appavailability/flutter_appavailability.dart';

void main() {
  SystemChrome.setEnabledSystemUIOverlays([]);
  runApp(Example());
}

Future<void> getApp() async {

  if (Platform.isAndroid) {

    installedApps = await AppAvailability.getInstalledApps();

    print(await AppAvailability.checkAvailability("com.android.chrome"));

    print(await AppAvailability.isAppEnabled("com.android.chrome"));

  }
  else if (Platform.isIOS) {
    installedApps = iOSApps;

    print(await AppAvailability.checkAvailability("calshow://"));

  }

}

List<Map<String, String>> installedApp;
List<Map<String, String>> installedApps;
List<Map<String, String>> iOSApps = [
  {
    "app_name": "Calendar",
    "package_name": "calshow://"
  },
  {
    "app_name": "Facebook",
    "package_name": "fb://"
  },
  {
    "app_name": "Whatsapp",
    "package_name": "whatsapp://"
  }
];

class Example extends StatefulWidget {

  @override 
    ExampleState createState() => ExampleState();

}

class ExampleState extends State<Example> {

  @override
    Widget build(BuildContext context) {
      return MaterialApp (
        debugShowCheckedModeBanner: false,
        home: Scaffold (
          body: Container (
            color: Colors.black,
            child: AppList ()
          )  
        ),
      );
    }

}

class AppList extends StatefulWidget {

  @override
    AppListState createState() => AppListState();

  AppList({Key key, this.child}) : super(key: key);

  final Widget child;

}

class AppListState extends State<AppList> {

  Widget child;

  List<Map<String, String>> _installedApps;

  @override
    void initState() {
      super.initState();
    }

  getApps() {
    setState(() {
      installedApps = _installedApps;
      getApp();
    });
  }

  @override
    Widget build(BuildContext context) {

      if (installedApps == null)
        getApps();

      return ListView.builder( 
        itemCount: installedApps == null ? 0 : installedApps.length,
        itemBuilder: (context, index) {
          return ListTile (
            title: Text(installedApps[index]["app_name"])
          );
        },
     );
   }

}
Fredelia answered 6/1, 2019 at 3:53 Comment(0)
R
3

Your Example Running

This is your example with the changes:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'dart:async';
import 'dart:io';

//import 'package:flutter_appavailability/flutter_appavailability.dart';

typedef Widget MyListTileBuilder(int index);

void main() {
  SystemChrome.setEnabledSystemUIOverlays([]);
  runApp(Example());
}

Future<void> getApp() async {

  if (Platform.isAndroid) {

    //installedApps = await AppAvailability.getInstalledApps();

    //print(await AppAvailability.checkAvailability("com.android.chrome"));

    //print(await AppAvailability.isAppEnabled("com.android.chrome"));

  }
  else if (Platform.isIOS) {
    installedApps = iOSApps;

    //print(await AppAvailability.checkAvailability("calshow://"));

  }

}

List<Map<String, String>> installedApp;
List<Map<String, String>> installedApps=[
  {"app_name":"app1"},
  {"app_name":"app2"},
  {"app_name":"app3"},
];
List<Map<String, String>> iOSApps = [
  {
    "app_name": "Calendar",
    "package_name": "calshow://"
  },
  {
    "app_name": "Facebook",
    "package_name": "fb://"
  },
  {
    "app_name": "Whatsapp",
    "package_name": "whatsapp://"
  }
];

class Example extends StatefulWidget {

  @override 
    ExampleState createState() => ExampleState();

}

class ExampleState extends State<Example> {

  Widget MyListTileBuilderImplementation (int index) {
    return ListTile ( 
                  title: Text(installedApps[index]["app_name"] + "  index:" + index.toString()) //this is the text
                );
  }

  @override
    Widget build(BuildContext context) {
      return MaterialApp (
        debugShowCheckedModeBanner: false,
        home: Scaffold (
          body: Container (
            color: Colors.white,
            child: AppList (childBuilder: this.MyListTileBuilderImplementation)
          )  
        ),
      );
    }

}

class AppList extends StatefulWidget {

  @override
    AppListState createState() => AppListState();

  AppList({Key key, this.childBuilder}) : super(key: key);

  final MyListTileBuilder childBuilder;

}

class AppListState extends State<AppList> {

  List<Map<String, String>> _installedApps;

  @override
    void initState() {
      super.initState();
    }

  getApps() {
    setState(() {
      installedApps = _installedApps;
      getApp();
    });
  }

  @override
    Widget build(BuildContext context) {

      if (installedApps == null)
        getApps();

      return ListView.builder( 
        itemCount: installedApps == null ? 0 : installedApps.length,
        itemBuilder: (context, index) {
          return  widget.childBuilder(index);
        },
     );
   }

}
Reservation answered 6/1, 2019 at 6:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.