简体   繁体   中英

How can I add 3 widgets in one?

I am trying to show 3 widgets with 3 different on tap functions, but it is not working. So what I want is the whole widget split in 3 different widgets so I can call widget 1 widget 2 or widget 3. But this is not working and I don't know why exactly. I have this videos collection where users videos are uploaded with 3 hashtags and what I want is that the user can search for one hashtag no matter which one, but it always shows all 3 hashtags instead of the one which the user searched for. And that is what I mean with 3 different widgets.

Here is my code:


class Openalldocs extends StatefulWidget {
  final TextEditingController searchinginput;
  static const route = '/openalldocs';

  const Openalldocs({Key key, this.searchinginput}) : super(key: key);

  @override
  _OpenalldocsState createState() => _OpenalldocsState();
}

class _OpenalldocsState extends State<Openalldocs> {
  List _allResults = [];
  List _resultsList = [];
  Future resultsLoaded;
  bool nosuerfound = false;
  String searchresult;

  @override
  void initState() {
    super.initState();
    widget.searchinginput.addListener(_onsearchChanged);
    setState(() {
      nosuerfound = true;
    });
  }

  @override
  void dispose() {
    widget.searchinginput.removeListener(_onsearchChanged());

    super.dispose();
  }

  @override
  void didChangeDependencies() {
    widget.searchinginput.text;
    resultsLoaded = getusers();
    super.didChangeDependencies();
  }

  _onsearchChanged() {
    setState(() {
      nosuerfound = false;
    });
    searchResults();
  }

  searchResults() {
    var showResults = [];
    if (widget.searchinginput.text != "") {
      for (var tripsnapshot in _allResults) {
        var title = DatbaseService.instance
            .videosfromsnapshot(tripsnapshot)
            .hashtag1
            .toLowerCase();
        print(title);
        var title2 = DatbaseService.instance
            .videosfromsnapshot(tripsnapshot)
            .hashtag3
            .toLowerCase();
        print(title);
        var title3 = DatbaseService.instance
            .videosfromsnapshot(tripsnapshot)
            .hashtag2
            .toLowerCase();
        print(title);
        if (title.contains(widget.searchinginput.text.toLowerCase()) ||
            title2.contains(widget.searchinginput.text.toLowerCase()) ||
            title3.contains(widget.searchinginput.text.toLowerCase())) {
          setState(() {
            nosuerfound = true;
          });
          showResults.add(tripsnapshot);
        }
      }
    } else {
      setState(() {
        nosuerfound = true;
      });
      showResults = List.from(_allResults);
    }
    setState(() {
      _resultsList = showResults;
    });
  }

  getusers() async {
    var firestore = FirebaseFirestore.instance;
    QuerySnapshot qn = await firestore.collection('videos').get();
    if (!mounted) return;

    setState(() {
      _allResults = qn.docs;
    });
    searchResults();
    return "Complete";
  }

  @override
  Widget build(BuildContext context) {
    final user = Provider.of<Userforid>(context);
    if (nosuerfound == true) {
      return ListView.builder(
        itemCount: _resultsList.length,
        itemBuilder: (BuildContext context, int index) {
          return Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                InkWell(
                  onTap: () {
                  },
                  child: Column(
                    children: <Widget>[
                      Column(
                        children: [
                          HighlightedMatchesText(
                            searchString: widget.searchinginput.text,
                            content: _resultsList[index].data()['hashtag1'],
                          ),
                        ],
                      ),
                      SizedBox(height: 3),
                    ],
                  ),
                ),
                SizedBox(height: 6),
                InkWell(
                  onTap: () {
                  },
                  child: Column(
                    children: <Widget>[
                      Column(
                        children: [
                          HighlightedMatchesText(
                            searchString: widget.searchinginput.text,
                            content: _resultsList[index].data()['hashtag2'],
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
                SizedBox(height: 6),
                InkWell(
                  onTap: () {
                
                  },
                  child: Column(
                    children: <Widget>[
                      Column(
                        children: [
                          HighlightedMatchesText(
                            searchString: widget.searchinginput.text,
                            content: _resultsList[index].data()['hashtag3'],
                          ),
                        ],
                      ),
                      SizedBox(height: 3),
                    ],
                  ),
                ),
                SizedBox(height: 6),
              ]);
        },
      );
    } else {
      return Padding(
        padding: const EdgeInsets.fromLTRB(0, 30, 0, 0),
        child: Center(
          child: Container(
              child: Text(
            "No Hashtag found",
            style: TextStyle(fontSize: 16),
          )),
        ),
      );
    }
  }
}

Your onTap handlers are empty, so nothing will happen actually when tapping.

To achieve what you are trying to, it is better to instead of creating widgets one by one in the Column children, create a for loop, and make the onTap and everything relative to it.

Here is how to achieve it (I took only a subsection of the code, the Column part):

return Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    // the AMOUNT is how many hashtags you want to show
    for (var i = 0; i < AMOUNT; i += 1) ...[
      // the SizedBox will only exist between the elements in the list
      // as before
      if (i != 0) SizedBox(height: 6),
      // create a builder to allow declaring a variable 
      Builder(
        builder: (context) {
          // declare the hashtag variable
          final hashtag = 'hashtag$i';

          return InkWell(
            onTap: () {
              // do something with the hashtag stored in the variable
              // this will make it relative to the element in the list
            },
            child: Column(
              children: <Widget>[
                // why is there a Column inside another with only one child?
                // I would recommend to remove it
                Column(
                  children: [
                    HighlightedMatchesText(
                      searchString: widget.searchinginput.text,
                      // notice how I am using the hashtag variable here
                      // instead of a constant? ('hashtag1'), by the way
                      // the for loop will make the hashtag start at 0
                      // you can change it by increment in the declaration
                      // `final hashtag = 'hashtag${i+1}'`, if you want
                      // the existing behavior
                      content: _resultsList[index].data()[hashtag],
                    ),
                  ],
                ),
                // what is this? if it is to add more space between the items
                // in the list, I recommend removing it from here, and add it
                // to the first `SizedBox` in the for loop
                // in case you do that, the Column that this widget belong
                // would also only now contain one widget, so, there is no
                // need to have it
                SizedBox(height: 3),
              ],
            ),
          ),
        },
      );
    ],
  ],
);

I added a lot of comments, I hope they help you to achieve what you are trying to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM