Pular para o conteúdo principal

Flutter PHP MySQL – Preencher ListView com imagens e texto

Flutter é um framework para criação de aplicativos móveis, tanto para Android quanto para iOS. Na verdade, atualmente você pode até usá-lo para criar aplicativos da Web e de desktop. É uma estrutura madura e bem suportada e atualmente está em alta.

O MySQL, por outro lado, é um banco de dados usado principalmente para hospedar dados para aplicativos da Web e móveis. É gratuito e é provavelmente o framework RDBMS mais popular do mercado. Geralmente gostamos de usá-lo com PHP, que é uma linguagem de programação do lado do servidor. PHP e MySQL é uma combinação que alimenta a maior parte da web.

Nesta lição, queremos ver como trabalhar com o banco de dados MySQL e o aplicativo flutter. Simplesmente executamos um HTTP GET no servidor PHP MySQL, baixamos os dados e preenchemos nossa exibição de lista personalizada com imagens e texto. Então, quando um único cartão em nosso listview é clicado, abrimos uma página de detalhes passando os dados que baixamos do mysql.

Demonstração

Aqui está a demonstração do que é criado no projeto.

Vídeo tutorial

Aqui está o vídeo tutorial:

1. PHP

Primeiro, precisamos escrever um código PHP que irá:

  1. Conecte-se ao banco de dados mysql usando a classe mysqli.
  2. Selecione todos os registros de nossa tabela de banco de dados mysql.
  3. Retorne os resultados para um array PHP.
  4. Codifique esse array em JSON e imprima-o para o chamador.
(a). index.php

Este é o único arquivo que temos. Nós escrevemos código PHP Orientado a Objetos. A primeira etapa neste arquivo é criar uma classe Constants que conterá nossas credenciais de banco de dados. Lembre-se de que estamos hospedando nosso banco de dados no MySQL, portanto, precisamos definir credenciais como nome do banco de dados, nome de usuário e senha.

No arquivo index.php escrevemos a tag PHP de abertura:

<?php

Em seguida, crie a classe com credenciais de banco de dados estáticas:

class Constants
{
//DATABASE DETAILS
static $DB_SERVER="localhost";
static $DB_NAME="spacecraftsDB";
static $USERNAME="root";
static $PASSWORD="";

Em seguida, defina a instrução sql para selecionar todos os dados do banco de dados:

    static $SQL_SELECT_ALL="SELECT * FROM spacecraftsTB";
}

No mesmo arquivo php, crie outra classe que hospedará nossos métodos CRUD:

class Spacecrafts
{

Nesta aula vamos definir uma função para se conectar ao nosso banco de dados usando mysqli. Passamos o servidor de banco de dados, nome do banco de dados, nome de usuário e senha para o construtor de nossa classe mysqli. Então, se a conexão for errática, retornamos null, caso contrário, retornamos nossa instância mysqli:

    public function connect()
{
$con=new mysqli(Constants::$DB_SERVER,Constants::$USERNAME,Constants::$PASSWORD,Constants::$DB_NAME);
if($con->connect_error)
{
// echo "Unable To Connect"; - For debug
return null;
}else
{
//echo "Connected"; - For debug
return $con;
}
}

A próxima função nos permitirá selecionar dados de nosso banco de dados mysql. Recuperamos os dados do banco de dados e, em seguida, colocamos esses dados em uma matriz, depois codificamos e imprimimos essa matriz:

    public function select()
{
$con=$this->connect();
if($con != null)
{
$result=$con->query(Constants::$SQL_SELECT_ALL);
if($result->num_rows>0)
{
$spacecrafts=array();
while($row=$result->fetch_array())
{
array_push($spacecrafts, array("id"=>$row['id'],"name"=>$row['name'],
"propellant"=>$row['propellant'],"destination"=>$row['destination'],
"image_url"=>$row['image_url'],"technology_exists"=>$row['technology_exists']));
}
print(json_encode(array_reverse($spacecrafts)));
}else
{
print(json_encode(array("PHP EXCEPTION : CAN'T RETRIEVE FROM MYSQL. ")));
}
$con->close();
}else{
print(json_encode(array("PHP EXCEPTION : CAN'T CONNECT TO MYSQL. NULL CONNECTION.")));
}
}

Aqui está o código completo do index.php:

<?php
class Constants
{
//DATABASE DETAILS
static $DB_SERVER="localhost";
static $DB_NAME="spacecraftsDB";
static $USERNAME="root";
static $PASSWORD="";
//STATEMENTS
static $SQL_SELECT_ALL="SELECT * FROM spacecraftsTB";
}
class Spacecrafts
{
/*******************************************************************************************************************************************/
/*
1.CONNECT TO DATABASE.
2. RETURN CONNECTION OBJECT
*/
public function connect()
{
$con=new mysqli(Constants::$DB_SERVER,Constants::$USERNAME,Constants::$PASSWORD,Constants::$DB_NAME);
if($con->connect_error)
{
// echo "Unable To Connect"; - For debug
return null;
}else
{
//echo "Connected"; - For debug
return $con;
}
}
/*******************************************************************************************************************************************/
/*
1.SELECT FROM DATABASE.
*/
public function select()
{
$con=$this->connect();
if($con != null)
{
$result=$con->query(Constants::$SQL_SELECT_ALL);
if($result->num_rows>0)
{
$spacecrafts=array();
while($row=$result->fetch_array())
{
array_push($spacecrafts, array("id"=>$row['id'],"name"=>$row['name'],
"propellant"=>$row['propellant'],"destination"=>$row['destination'],
"image_url"=>$row['image_url'],"technology_exists"=>$row['technology_exists']));
}
print(json_encode(array_reverse($spacecrafts)));
}else
{
print(json_encode(array("PHP EXCEPTION : CAN'T RETRIEVE FROM MYSQL. ")));
}
$con->close();
}else{
print(json_encode(array("PHP EXCEPTION : CAN'T CONNECT TO MYSQL. NULL CONNECTION.")));
}
}
}
$spacecrafts=new Spacecrafts();
$spacecrafts->select();
//end

2. Dardo

A próxima parte é escrever nosso código Dart. Dart é a linguagem de programação que usamos para criar nosso aplicativo Flutter. Temos apenas um arquivo:

(a). main.dart

Comece adicionando importações:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' show get;
import 'dart:convert';

Crie uma classe chamada Spacecraft para representar uma nave espacial. Esta é a nossa classe modelo. Definimos propriedades desta espaçonave como instâncias desta classe. Essas propriedades incluem id, nome, URL da imagem e propulsor.

class Spacecraft {
final String id;
final String name, imageUrl, propellant;

Essas propriedades serão recebidas por meio do construtor:

  Spacecraft({
this.id,
this.name,
this.imageUrl,
this.propellant,
});

Teremos uma função responsável por converter dados JSON em nosso objeto Spacecraft:

  factory Spacecraft.fromJson(Map<String, dynamic> jsonData) {
return Spacecraft(
id: jsonData['id'],
name: jsonData['name'],
propellant: jsonData['propellant'],
imageUrl: "http://192.168.12.2/PHP/spacecrafts/images/"+jsonData['image_url'],
);
}
}

Também precisaremos criar uma tela que listará nossos dados. Listamos nossos dados em um ListView. Portanto, precisamos criar um item ListView. Quando esse item ListView for clicado, abriremos a página de detalhes e mostraremos os resultados em outra tela:

  Widget createViewItem(Spacecraft spacecraft, BuildContext context) {
return new ListTile(
title: new Card(
elevation: 5.0,
child: new Container(
decoration: BoxDecoration(border: Border.all(color: Colors.orange)),
padding: EdgeInsets.all(20.0),
margin: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Padding(
child: Image.network(spacecraft.imageUrl),
padding: EdgeInsets.only(bottom: 8.0),
),
Row(children: <Widget>[
Padding(
child: Text(
spacecraft.name,
style: new TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.right,
),
padding: EdgeInsets.all(1.0)),
Text(" | "),
Padding(
child: Text(
spacecraft.propellant,
style: new TextStyle(fontStyle: FontStyle.italic),
textAlign: TextAlign.right,
),
padding: EdgeInsets.all(1.0)),
]),
],
),
),
),
onTap: () {
//We start by creating a Page Route.
//A MaterialPageRoute is a modal route that replaces the entire
//screen with a platform-adaptive transition.
var route = new MaterialPageRoute(
builder: (BuildContext context) =>
new SecondScreen(value: spacecraft),
);
//A Navigator is a widget that manages a set of child widgets with
//stack discipline.It allows us navigate pages.
Navigator.of(context).push(route);
});
}
}

Você pode estar interessado em saber como baixamos os dados JSON do servidor. O primeiro passo é definir uma função que retorne um objeto Future. Este método será assíncrono para que não bloqueemos nossa interface de usuário Thread. O parâmetro genérico desta função será uma lista de naves:

Future<List<Spacecraft>> downloadJSON() async {

Em seguida, defina um endpoint JSON. Esta é a URL na qual realizaremos uma solicitação HTTP GET. Em seguida, execute esse endpoint usando a função get():

  final jsonEndpoint =
"http://192.168.12.2/PHP/spacecrafts";
final response = await get(jsonEndpoint);

Também verificaremos o código de resposta se obtivermos sucesso. Um código de status de resposta de 200 indica sucesso, que comunicamos com sucesso ao servidor. Portanto, decodificamos o corpo da resposta JSON em uma lista. É essa lista que iremos renderizar em nossa listview:

  if (response.statusCode == 200) {
List spacecrafts = json.decode(response.body);
return spacecrafts
.map((spacecraft) => new Spacecraft.fromJson(spacecraft))
.toList();
} else
throw Exception('We were not able to successfully download the json data.');
}

Aqui está o código completo:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' show get;
import 'dart:convert';
class Spacecraft {
final String id;
final String name, imageUrl, propellant;
Spacecraft({
this.id,
this.name,
this.imageUrl,
this.propellant,
});
factory Spacecraft.fromJson(Map<String, dynamic> jsonData) {
return Spacecraft(
id: jsonData['id'],
name: jsonData['name'],
propellant: jsonData['propellant'],
imageUrl: "http://192.168.12.2/PHP/spacecrafts/images/"+jsonData['image_url'],
);
}
}
class CustomListView extends StatelessWidget {
final List<Spacecraft> spacecrafts;
CustomListView(this.spacecrafts);
Widget build(context) {
return ListView.builder(
itemCount: spacecrafts.length,
itemBuilder: (context, int currentIndex) {
return createViewItem(spacecrafts[currentIndex], context);
},
);
}
Widget createViewItem(Spacecraft spacecraft, BuildContext context) {
return new ListTile(
title: new Card(
elevation: 5.0,
child: new Container(
decoration: BoxDecoration(border: Border.all(color: Colors.orange)),
padding: EdgeInsets.all(20.0),
margin: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Padding(
child: Image.network(spacecraft.imageUrl),
padding: EdgeInsets.only(bottom: 8.0),
),
Row(children: <Widget>[
Padding(
child: Text(
spacecraft.name,
style: new TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.right,
),
padding: EdgeInsets.all(1.0)),
Text(" | "),
Padding(
child: Text(
spacecraft.propellant,
style: new TextStyle(fontStyle: FontStyle.italic),
textAlign: TextAlign.right,
),
padding: EdgeInsets.all(1.0)),
]),
],
),
),
),
onTap: () {
//We start by creating a Page Route.
//A MaterialPageRoute is a modal route that replaces the entire
//screen with a platform-adaptive transition.
var route = new MaterialPageRoute(
builder: (BuildContext context) =>
new SecondScreen(value: spacecraft),
);
//A Navigator is a widget that manages a set of child widgets with
//stack discipline.It allows us navigate pages.
Navigator.of(context).push(route);
});
}
}
//Future is n object representing a delayed computation.
Future<List<Spacecraft>> downloadJSON() async {
final jsonEndpoint =
"http://192.168.12.2/PHP/spacecrafts";
final response = await get(jsonEndpoint);
if (response.statusCode == 200) {
List spacecrafts = json.decode(response.body);
return spacecrafts
.map((spacecraft) => new Spacecraft.fromJson(spacecraft))
.toList();
} else
throw Exception('We were not able to successfully download the json data.');
}
class SecondScreen extends StatefulWidget {
final Spacecraft value;
SecondScreen({Key key, this.value}) : super(key: key);

_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {

Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Detail Page')),
body: new Container(
child: new Center(
child: Column(
children: <Widget>[
Padding(
child: new Text(
'SPACECRAFT DETAILS',
style: new TextStyle(fontWeight: FontWeight.bold,fontSize: 20.0),
textAlign: TextAlign.center,
),
padding: EdgeInsets.only(bottom: 20.0),
),
Padding(
//<code>widget
Download

Aqui estão os recursos de referência:

Não.LocalizaçãoLink
1.GitHubDownload direto
2.GitHubNavegar
3.YouTubeTutorial em vídeo
4.YouTubeCanal de TV ProgrammingWizards
5.CamposhaVeja todos os tutoriais do Flutter