Turf
Turf

Reputation: 434

Using TabBar like filter

i'm trying to make a Tabbar that appear in a new page when the search icon in pressed. The code works fine but i don't know how to implement this tabbar. I want to use the tabbar for splitting the search info, each icon has to show only specific info.

I guess each icon has a specific list?

This is my search_tool.dart this appear when the icon button at the main page is pressed

[EDIT] Now the result is shown correctly, but when I press the search box to write the error message contained in buildSuggestion always appears, instead it should only show the list with the relative records and if something not belonging to that category is searched then it must give the error message

import 'package:flutter/material.dart';
import 'package:solaris/lista_data.dart';
import 'constants.dart';

class LinkItemsSearch extends SearchDelegate<LinkItem>{
  @override
  PreferredSizeWidget buildBottom(BuildContext context) {

    return PreferredSize(
      child: Container(
        alignment: Alignment.center,
        child: SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: Row(
            children: [
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: ElevatedButton(
                  onPressed: () {
                    query = 'Apps';
                    this.showResults(context);
                  },
                  child: Text('Apps'),
                ),
              ),
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: ElevatedButton(
                  onPressed: () {
                    query = 'Movies';
                    this.showResults(context);
                  },
                  child: Text('Movies'),
                ),
              ),
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: ElevatedButton(
                  onPressed: () {
                    query = 'Games';
                    this.showResults(context);
                  },
                  child: Text('Games'),
                ),
              ),
            ],
          ),
        ),
      ),
      preferredSize: Size.fromHeight(60),
    );
  }

  @override
  List<Widget> buildActions(BuildContext context) {
    return [IconButton(icon: Icon(Icons.clear),onPressed: () { query=""; },)];
  }

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(onPressed: () { Navigator.pop(context); }, icon: Icon(Icons.arrow_back),);
  }

  @override
  Widget buildResults(BuildContext context) {

    var mylist = loadLinkItem().where((p) => p.description.contains(query)).toList();

    return Container(
      color: blue,
      child: ListView.builder(
          itemCount: mylist.length,
          itemBuilder: (context,index){
            final LinkItem listitem = mylist[index];
            return Container(
              color: blue,
              child: ListTile(
                title:InkWell(
                  onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget> [
                      Text(listitem.title, style: TextStyle(color: Colors.white),),
                      Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
                      Divider(color: white,),
                    ],
                  ),
                ),
              ),
            );
          }
      ),
    );
  }

  @override
  Widget buildSuggestions(BuildContext context) {

        final mylist = query.isEmpty? loadLinkItem():loadLinkItem().where((p) => p.description.contains(RegExp(query, caseSensitive: false))).toList();

    return mylist.isEmpty?
    Container(
      color: red,
      child: Center(child: Text('No Result Found . . .', style: TextStyle(color: Colors.white,fontSize: 20,))),
    ):Container(
      color: blue,
      child: ListView.builder(
          itemCount: mylist.length,
          itemBuilder: (context,index){
            final LinkItem listitem = mylist[index];
            return Container(
              color: blue,
              child: ListTile(onTap: (){ showResults(context);},
                title:InkWell(
                  onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget> [
                      Text(listitem.title, style: TextStyle(color: Colors.white),),
                      Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
                      Divider(color: white,),
                    ],
                  ),
                ),
              ),
            );
          }
      ),
    );
  }

}

Search icon

IconButton(onPressed:(){
   showSearch(context: context, delegate: LinkItemsSearch());
}, icon: Icon(Icons.search),),

List

class LinkItem{
  final String title;
  final String description;
  final link;
  LinkItem({
    required this.title,
    required this.description,
    required this.link,
});
}

List<LinkItem> loadLinkItem(){
  var link = <LinkItem>[
    LinkItem(
        title: 'Title1',
        description: 'Apps',
        link: Title1(),
    ),LinkItem(
        title: 'Title2',
        description: 'Movies',
        link: Title2(),
    ),LinkItem(
        title: 'Title3',
        description: 'Games',
        link: Title3(),
    ),
  ];
  return link;
}

Upvotes: 0

Views: 440

Answers (2)

Turf
Turf

Reputation: 434

FIX

import 'package:flutter/material.dart';
import 'package:solaris/lista_data.dart';
import 'constants.dart';

class LinkItemsSearch extends SearchDelegate<LinkItem>{
  @override
  PreferredSizeWidget buildBottom(BuildContext context) {

    return PreferredSize(
      child: Container(
        alignment: Alignment.center,
        child: SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: Row(
            children: [
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: ElevatedButton(
                  onPressed: () {
                    query = 'Apps';
                    this.showResults(context);
                  },
                  child: Text('Apps'),
                ),
              ),
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: ElevatedButton(
                  onPressed: () {
                    query = 'Movies';
                    this.showResults(context);
                  },
                  child: Text('Movies'),
                ),
              ),
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: ElevatedButton(
                  onPressed: () {
                    query = 'Games';
                    this.showResults(context);
                  },
                  child: Text('Games'),
                ),
              ),
            ],
          ),
        ),
      ),
      preferredSize: Size.fromHeight(60),
    );
  }

  @override
  List<Widget> buildActions(BuildContext context) {
    return [IconButton(icon: Icon(Icons.clear),onPressed: () { query=""; },)];
  }

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(onPressed: () { Navigator.pop(context); }, icon: Icon(Icons.arrow_back),);
  }

  @override
  Widget buildResults(BuildContext context) {

    var mylist = loadLinkItem().where((p) => p.description.contains(query)).toList();

    return Container(
      color: blue,
      child: ListView.builder(
          itemCount: mylist.length,
          itemBuilder: (context,index){
            final LinkItem listitem = mylist[index];
            return Container(
              color: blue,
              child: ListTile(
                title:InkWell(
                  onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget> [
                      Text(listitem.title, style: TextStyle(color: Colors.white),),
                      Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
                      Divider(color: white,),
                    ],
                  ),
                ),
              ),
            );
          }
      ),
    );
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    final mylist = query.isEmpty? loadLinkItem():loadLinkItem().where((p) => p.description.contains(RegExp(query, caseSensitive: false))).toList();
    return mylist.isEmpty?
    Container(
      color: red,
      child: Center(child: Text('No Result Found . . .', style: TextStyle(color: Colors.white,fontSize: 20,))),
    ):Container(
      color: blue,
      child: ListView.builder(
          itemCount: mylist.length,
          itemBuilder: (context,index){
            final LinkItem listitem = mylist[index];
            return Container(
              color: blue,
              child: ListTile(onTap: (){ showResults(context);},
                title:InkWell(
                  onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget> [
                      Text(listitem.title, style: TextStyle(color: Colors.white),),
                      Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
                      Divider(color: white,),
                    ],
                  ),
                ),
              ),
            );
          }
      ),
    );
  }

}

Upvotes: 0

zpouip
zpouip

Reputation: 787

You can override the buildBottom method in your LinkItemsSearch:

@override
PreferredSizeWidget buildBottom(BuildContext context) {
  return PreferredSize(
    child: Container(
      alignment: Alignment.center,
      child: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          children: [
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 8),
              child: ElevatedButton(
                onPressed: () {
                  query = 'Apps';

                  mylist = loadLinkItem()
                      .where((p) => p.description.contains(query))
                      .toList();

                  this.showResults(context);
                },
                child: Text('Apps'),
              ),
            ),
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 8),
              child: ElevatedButton(
                onPressed: () {
                  query = 'Movies';

                  mylist = loadLinkItem()
                      .where((p) => p.description.contains(query))
                      .toList();

                  this.showResults(context);
                },
                child: Text('Movies'),
              ),
            ),
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 8),
              child: ElevatedButton(
                onPressed: () {
                  query = 'Games';

                  mylist = loadLinkItem()
                      .where((p) => p.description.contains(query))
                      .toList();

                  this.showResults(context);
                },
                child: Text('Games'),
              ),
            ),
          ],
        ),
      ),
    ),
    preferredSize: Size.fromHeight(60),
  );
}

For this to work, you have to create myList on the top of your LinkItemsSearch and reuse it when filtering everywhere. Also, I just updated loadLinkItem method to have some input for filtering:

List<LinkItem> loadLinkItem() {
  var link = <LinkItem>[
    LinkItem(
      title: 'Title1',
      description: 'Movies',
      link: '',
    ),
    LinkItem(
      title: 'Title2',
      description: 'Games',
      link: '',
    ),
    LinkItem(
      title: 'Title3',
      description: 'Apps',
      link: '',
    ),
  ];
  return link;
}

Of course, I have not completely matched your style, so I did not style buttons as you need it, you might higher bottom bar than 60 as I used. I also have not attached any on press handlers since I am not sure what should they do, but it looks as it is expected: https://i.sstatic.net/osUkt.png

I wrapped them with a Column and SingleChildScrollView in case you have more of those items and they need to be scrollable: https://i.sstatic.net/FyWVX.png

You can even add some conditions in cases when you don't need this bottom bar to be displayed and in that case, you can just return null from the buildBottom method.

Upvotes: 1

Related Questions