'Trying to show specific information when clicking in a button
I building an app that show an image from the firestore that is saved in the storage. I already can show it but i'm trying to change it when the user clicks in the button it show only some specific images.
The way i have this set up is, i have 2 lists with data for two screens. The data for the first screen
import 'package:flutter/material.dart';
import '../models/disciplinas.dart';
const DUMMY_DISCIPLINA = const [
Disciplina(
id: 'd1',
title: 'Português',
color: Color.fromARGB(255, 28, 209, 216),
),
Disciplina(
id: 'd2',
title: 'Matemática',
color: Color.fromARGB(255, 83, 48, 195),
),
Disciplina(
id: 'd3',
title: 'Inglês',
color: Color.fromARGB(255, 235, 153, 46),
),
Disciplina(
id: 'd4',
title: 'AI',
color: Color.fromARGB(255, 28, 209, 216),
),
Disciplina(
id: 'd5',
title: 'PSI',
color: Color.fromARGB(255, 83, 48, 195),
),
Disciplina(
id: 'd6',
title: 'FQ',
color: Color.fromARGB(255, 235, 153, 46),
),
Disciplina(
id: 'd7',
title: 'Espanhol',
color: Color.fromARGB(255, 28, 209, 216),
),
Disciplina(
id: 'd8',
title: 'ARQC',
color: Color.fromARGB(255, 90, 57, 200),
),
Disciplina(
id: 'd9',
title: 'RC',
color: Color.fromARGB(255, 235, 153, 46),
),
Disciplina(
id: 'd10',
title: 'TIC',
color: Color.fromARGB(255, 28, 209, 216),
),
Disciplina(
id: 'd11',
title: 'SO',
color: Color.fromARGB(255, 83, 48, 195),
),
];
In the screen i just create a map and show it
import 'package:flutter/material.dart';
import '../data/dummy_data.dart';
import 'disciplina_item.dart';
class DisciplinasScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//segunda base da app
appBar: AppBar(
//cria uma barra na parte superior da app
title: const Text('Disciplinas'), //titulo da appbar
toolbarHeight: 50,
),
body: GridView(
//fazer com que os buttons fiquem organizados e scrollable^
padding: const EdgeInsets.all(25),
children: DUMMY_DISCIPLINA //chama a lista da pagina dummy_data
.map(
//chama uma lista
(dicData) => DisciplinaItem(
//guarda na variavel 'dicData' as variveis da função DisciplinaItem da disciplina_item.dart
dicData.id.toString(),
dicData.title.toString(), //aponta para o title da função
dicData.color, //aponta para a cor da função
),
)
.toList(),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
//função do flutter que deixa mexer com a grid autonomamente
maxCrossAxisExtent:
200, //o maximo de width que a grid toma é de 200 pixeis
childAspectRatio: 3 / 2, //cada grid toma o ratio de 3/2
crossAxisSpacing: 20, //espaçamento maximo é de 20 pixeis
mainAxisSpacing: 20, //espaçamento maximo é de 20 pixeis
),
),
);
}
}
from this
import 'package:flutter/material.dart';
import '../modulos/disciplina_modulos_screen.dart';
class DisciplinaItem extends StatelessWidget {
//widget que não muda UI
final String id; //id da disciplina
final String title; //nome da disciplina
final Color color; //cor do background do "botão"
DisciplinaItem(
this.id,
this.title,
this.color,
); //aponta as variaveis para a propria class
void selectDisciplina(BuildContext ctx) {
Navigator.of(ctx).pushNamed(
DisciplinaModuloScreen.routeName, //route situada no main
arguments: {
//argumentos que vão ser passados para a outra pagina sem o utilizador ver
'id': id,
'title': title,
},
);
}
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () =>
selectDisciplina(context), //chama a função só quando é carregado
splashColor: Theme.of(context).primaryColor, //cor de quando é carregado
// borderRadius: BorderRadius.circular(15), //borda redonda
child: Container(
padding: const EdgeInsets.all(
15), //padding ao container de 15 pixeis em todos os lados
child: Text(
title,
style: Theme.of(context).textTheme.headline6,
), //mostra o title no container
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
color.withOpacity(
0.7,
), //cor que vai buscar ao ficheiro mas com opacidade reduzida
color,
],
begin: Alignment.center,
end: Alignment.center,
),
borderRadius: BorderRadius.circular(15), //botoes com bordas redondas
),
),
);
}
}
i also have the second screen that is also filtered with the info send the first page the screen
import 'package:flutter/material.dart';
import '../data/modulo_data.dart';
import '../modulos/modulo_item.dart';
class DisciplinaModuloScreen extends StatelessWidget {
static const routeName = '/disciplina-modulos';
//final String moduloId;
//final String moduloTitle;
//DisciplinaModuloScreen(
//this.moduloId,
//this.moduloTitle,
//);
@override
Widget build(BuildContext context) {
final routeArgs =
ModalRoute.of(context)?.settings.arguments as Map<String, String>;
final disciplinaId = routeArgs['id'];
final disciplinaTitle = routeArgs['title'];
final disciplinaModulo = DUMMY_MODULO.where((modulo) {
return modulo.modDisciplinaId!.contains(disciplinaId.toString());
}).toList();
return Scaffold(
appBar: AppBar(
title: Text('Módulos da disciplina ' + disciplinaTitle.toString()),
),
body: GridView.builder(
padding: const EdgeInsets.all(25),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
//função do flutter que deixa mexer com a grid autonomamente
maxCrossAxisExtent:
200, //o maximo de width que a grid toma é de 200 pixeis
childAspectRatio: 3 / 2, //cada grid toma o ratio de 3/2
crossAxisSpacing: 20, //espaçamento maximo é de 20 pixeis
mainAxisSpacing: 20, //espaçamento maximo é de 20 pixeis
),
itemBuilder: (ctx, index) {
return ModuloItem(
disciplinaModulo[index].modTitle.toString(),
disciplinaModulo[index].color,
);
},
itemCount: disciplinaModulo.length,
),
);
}
}
the list that has the data
import 'package:flutter/material.dart';
import '../../models/modulo.dart';
const DUMMY_MODULO = const [
Modulo(
modId: 'm1',
modDisciplinaId: [
'd1',
'd2',
'd3',
'd4',
'd5',
'd6',
'd7',
'd8',
'd9',
'd10',
'd11',
],
modTitle: 'Módulo 1',
color: Color.fromARGB(255, 28, 209, 216),
),
Modulo(
modId: 'm2',
modDisciplinaId: [
'd1',
'd2',
'd3',
'd4',
'd5',
'd6',
'd7',
'd8',
'd9',
'd10',
'd11',
],
modTitle: 'Módulo 2',
color: Color.fromARGB(255, 83, 48, 195),
),
Modulo(
modId: 'm3',
modDisciplinaId: [
'd1',
'd2',
'd3',
'd4',
'd5',
'd6',
'd7',
'd8',
'd9',
'd10',
'd11',
],
modTitle: 'Módulo 3',
color: Color.fromARGB(255, 235, 153, 46),
),
Modulo(
modId: 'm4',
modDisciplinaId: [
'd1',
'd2',
'd3',
'd4',
'd5',
'd6',
'd7',
'd8',
'd9',
'd11',
],
modTitle: 'Módulo 4',
color: Color.fromARGB(255, 28, 209, 216),
),
Modulo(
modId: 'm5',
modDisciplinaId: [
'd1',
'd2',
'd3',
'd4',
'd5',
'd6',
'd7',
'd8',
'd9',
'd11',
],
modTitle: 'Módulo 5',
color: Color.fromARGB(255, 83, 48, 195),
),
Modulo(
modId: 'm6',
modDisciplinaId: [
'd1',
'd2',
'd3',
'd4',
'd5',
'd6',
'd7',
'd9',
],
modTitle: 'Módulo 6',
color: Color.fromARGB(255, 235, 153, 46),
),
Modulo(
modId: 'm7',
modDisciplinaId: [
'd1',
'd2',
'd3',
'd5',
'd6',
'd9',
],
modTitle: 'Módulo 7',
color: Color.fromARGB(255, 28, 209, 216),
),
Modulo(
modId: 'm8',
modDisciplinaId: [
'd1',
'd2',
'd3',
'd5',
'd6',
'd9',
],
modTitle: 'Módulo 8',
color: Color.fromARGB(255, 90, 57, 200),
),
Modulo(
modId: 'm9',
modDisciplinaId: [
'd1',
'd2',
'd3',
'd5',
'd6',
'd9',
],
modTitle: 'Módulo 9',
color: Color.fromARGB(255, 235, 153, 46),
),
Modulo(
modId: 'm10',
modDisciplinaId: [
'd2',
'd5',
'd6',
],
modTitle: 'Módulo 10',
color: Color.fromARGB(255, 28, 209, 216),
),
Modulo(
modId: 'm11',
modDisciplinaId: [
'd5',
'd6',
],
modTitle: 'Módulo 11',
color: Color.fromARGB(255, 83, 48, 195),
),
Modulo(
modId: 'm12',
modDisciplinaId: [
'd5',
'd6',
],
modTitle: 'Módulo 12',
color: Color.fromARGB(255, 235, 153, 46),
),
Modulo(
modId: 'm13',
modDisciplinaId: [
'd5',
],
modTitle: 'Módulo 13',
color: Color.fromARGB(255, 28, 209, 216),
),
Modulo(
modId: 'm14',
modDisciplinaId: [
'd5',
],
modTitle: 'Módulo 14',
color: Color.fromARGB(255, 83, 48, 195),
),
Modulo(
modId: 'm15',
modDisciplinaId: [
'd5',
],
modTitle: 'Módulo 15',
color: Color.fromARGB(255, 235, 153, 46),
),
Modulo(
modId: 'm16',
modDisciplinaId: [
'd5',
],
modTitle: 'Módulo 16',
color: Color.fromARGB(255, 28, 209, 216),
),
Modulo(
modId: 'm17',
modDisciplinaId: [
'd5',
],
modTitle: 'Módulo 17',
color: Color.fromARGB(255, 83, 48, 195),
),
Modulo(
modId: 'm18',
modDisciplinaId: [
'd5',
],
modTitle: 'Módulo 18',
color: Color.fromARGB(255, 235, 153, 46),
),
Modulo(
modId: 'm19',
modDisciplinaId: [
'd5',
],
modTitle: 'Módulo 19',
color: Color.fromARGB(255, 28, 209, 216),
),
];
The problem is that, in the screen that is supost to show the info that is flitered by the buttons in these 2 screen(the ones above this), i could only filter with a variable that i asign a value (the variable is query)
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:pap_test/upload/upload_resumos_screen.dart';
class DownloadScreen extends StatefulWidget {
const DownloadScreen({Key? key}) : super(key: key);
static const routeName = '/downlaod-resumos';
@override
State<DownloadScreen> createState() => _DownloadScreenState();
}
class _DownloadScreenState extends State<DownloadScreen> {
// variavel que vai ser usada para procurar na base de dados
String query = '1';
// guardar o caminho da base de dados na variavel _firebaseFirestore
CollectionReference _firebaseFirestore =
FirebaseFirestore.instance.collection('images');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Resumos'),
),
// streamBuilder é usado para auto se construir de acordo com o snapshot(data recebida da base de dados)
body: StreamBuilder<QuerySnapshot>(
stream: _firebaseFirestore.snapshots().asBroadcastStream(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
// se o snapshot for null mostra o simbolo de loading
if (!snapshot.hasData) {
return Center(
// simbolo de loding
child: CircularProgressIndicator(),
);
} else {
if (snapshot.data!.docs
.where((QueryDocumentSnapshot<Object?>
element) => // campo da firestore
element['disciplina']
// como o campo é int tem que se passar para string
.toString()
.toLowerCase()
// onde (where) tiver (contains) a query igual ao que está nas disciplina
.contains(query.toLowerCase()))
.isEmpty) {
return Center(
child: Text(
'Por aqui está muito lento, carrega no botão e publica um resumo.',
style: Theme.of(context).textTheme.headline5,
textAlign: TextAlign.center,
),
);
} else {
return ListView(
children: [
// os ... permite nos adicinar varios widgets
// onde o campo da firestore disciplina for igual ao que está no query ele cria um mapa
...snapshot.data!.docs
.where((QueryDocumentSnapshot<Object?>
element) => // campo da firestore
element['disciplina']
// como o campo é int tem que se passar para string
.toString()
.toLowerCase()
// onde (where) tiver (contains) a query igual ao que está nas disciplina
.contains(query.toLowerCase()))
.map(
(QueryDocumentSnapshot<Object?> data) {
// guarda na variavel disciplina o que esta na firestore
final String descricao = data.get('descricao');
// guarda na variavel image o que esta na firestore
final image = data['url'];
// depois cria um ListTile em relação á data dada em cima
return ListTile(
onTap: () async {
//await FirebaseApi.downloadFile();
// fazer o downLoad
},
// mostra a imagem
leading: CircleAvatar(
backgroundImage: NetworkImage(image),
),
// mostra a disciplina
title: Text(
descricao.toString(),
style: Theme.of(context).textTheme.headline5,
),
);
},
)
],
);
}
// se nao for nulo
// fetch data
// mostra a data na consola
print(snapshot.data);
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// quando o botao é precionado vai para o UploadScreen
Navigator.of(context).pushNamed(UploadResumoScreen.routeName);
},
//cor do background
backgroundColor: Color.fromARGB(255, 28, 209, 216),
// tipo do icon
child: const Icon(Icons.add),
// cor do icon
foregroundColor: Colors.white,
),
);
}
}
class QueryMod {
const QueryMod(this.mod);
final String mod;
}
class QueryDisc {
const QueryDisc(this.disc);
final String disc;
}
if it can help, i'm uploading the images with this code (i passed the characters limit so the upload is in here https://drive.google.com/file/d/1yb9_3IrEzrkT37zpfLwkwxb7QYKU_k0e/view?usp=sharing )
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
