Flutter [ DataTable ]

Sou novo na programação Flutter. Montei uma pagina que ao chamar via menu gostaria de apresentar os dados em uma DataTable. Até consegui fazer isto, porém só apresenta os dados quando clico para mudar a ordem . Ou seja deveria abrir a tela carregando os dados, sem a necessidade de selecionar a mudança de ordem. Conseguem me dar essa força?

import ‘dart:convert’;

import ‘package:cibernetica/screens/modelDiscip.dart’;
import ‘package:flutter/material.dart’;
import ‘package:cibernetica/screens/loginuser.dart’;
import ‘package:http/http.dart’ as http;

class pagdisciplina extends StatefulWidget {
var oTbAluno;
pagdisciplina({this.oTbAluno});

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

class _pagdisciplinaState extends State {
var id = ModelDiscip.id;
List tbDiscip;
bool sort;

@override
void initState() {
sort = false;

setState(() {
  var tbtmp = getDisciplina(id);
  tbDiscip = getConvert(tbtmp);
});
super.initState();

}

onSortColum(int columnIndex, bool ascending) {
if (columnIndex == 0) {
if (ascending) {
setState(() {
tbDiscip.sort((a, b) => a.disciplina.compareTo(b.disciplina));
});
} else {
setState(() {
tbDiscip.sort((a, b) => b.disciplina.compareTo(a.disciplina));
});
}
}
}

DataTable dataBody() {
return DataTable(
sortAscending: sort,
sortColumnIndex: 0,
columns: [
DataColumn(
label: Text(“Disciplina”),
numeric: false,
tooltip: “Nome da disciplina”,
onSort: (columnIndex, ascending) {
setState(() {
sort = !sort;
});
onSortColum(columnIndex, ascending);
}),
DataColumn(
label: Text(“Professor”),
numeric: false,
tooltip: “Professor da disciplina”)
],
rows: tbDiscip
.map(
// ignore: non_constant_identifier_names
(ModelDiscip) => DataRow(cells: [
DataCell(Text(ModelDiscip.disciplina), onTap: () {
print(‘Selecionado ${ModelDiscip.disciplina}’);
}),
DataCell(
Text(ModelDiscip.professor),
),
]),
)
.toList(),
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(‘Disciplinas’),
),
body: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
verticalDirection: VerticalDirection.down,
children: [
Center(
child: dataBody(),
)
],
),
);
}

listaTrabalhos() {
return ListView.builder(
itemBuilder: (context, index) {
return ListTile(
title: Text(’’),
);
},
);
}

static Future<List> getDisciplina(int id) async {
String url =
http://facbrasil.com/mobile/educacional/trabalho/’ + id.toString();
final response = await http.get(
url,
headers: {‘Content-Type’: ‘application/json; charset=UTF-8’},
);
var convDataToJson = jsonDecode(response.body);
List listaDiscip = new List();

for (Map<String, dynamic> json in convDataToJson) {
  ModelDiscip lista = ModelDiscip.fromJson(json);
  listaDiscip.add(lista);
}
return listaDiscip;

}

List getConvert(Future<List> oLista) {
List listConvert = [];
oLista.then((value) =>
{if (value != null) value.forEach((item) => listConvert.add(item))});
return listConvert == null ? [] : listConvert;
}

1 Curtida

Olá Valdemir Rabelo,

Olhando para o seu código, percebo que o uso do setState não deveria estar dentro do método de inicialização.
Pelo seguintes motivos:

  1. O método initState é chamado apenas 1 única vez, na criação no widget (tela).
    Esse método deve conter instruções para inicialização dos objetos que compõem a tela.

  2. O método setState é utilizado para alterar os valores dos objetos após serem inicializados.

Então, como uma possível solução para o problema apresentado, ajusta o método sobre-escrito (initState):

@override
  void initState() {
    super.initState();
    sort = false;
    tbDiscip = List(); // inicializa a lista vazia

    getDisciplina(id); // método responsável por atualizar a lista de disciplinas
  }

A primeira instrução dentro deste método é fortemente recomendado chamar o método pai (super.initState();).
Em seguida, devemos inicializar a lista (tabela) das disciplinas, neste caso vazia.
Após a inicialização, devemos chamar o método responsável para obter as disciplinas, vale salientar que este método é assíncrono.
Então vamos fazer um pequeno ajuste nele.

Future<void> getDisciplina(int id) async {
    String url =
        'http://facbrasil.com/mobile/educacional/trabalho/' + id.toString();
    final response = await http.get(
      url,
      headers: {'Content-Type': 'application/json; charset=UTF-8'},
    );
    var convDataToJson = jsonDecode(response.body);
    List listaDiscip = new List();

    for (Map<String, dynamic> json in convDataToJson) {
      ModelDiscip lista = ModelDiscip.fromJson(json);
      listaDiscip.add(lista);
    }

    // atualiza a lista de disciplinas
    setState(() {
      tbDiscip = listaDiscip;
    });
  }

O ponto chave deste método, é que ele chama o método (setState) para atualizar a lista de disciplina, inicializada como vazia.

1 Curtida