Flutter PHP MySQL - 이미지와 텍스트로 ListView 채우기
Flutter는 Android 및 iOS용 모바일 앱을 만들기 위한 프레임워크입니다. 실제로 현재 웹 및 데스크톱 앱을 만드는 데 사용할 수도 있습니다. 성숙하고 잘 지원되는 프레임워크이며 현재 유행하고 있습니다.
반면에 MySQL은 웹 및 모바일 앱용 데이터를 호스팅하는 데 주로 사용되는 데이터베이스입니다. 무료이며 아마도 시장에서 가장 인기 있는 RDBMS 프레임워크일 것입니다. 일반적으로 우리는 서버 측 프로그래밍 언어인 PHP와 함께 사용하는 것을 좋아합니다. PHP와 MySQL은 대부분의 웹을 강화하는 조합입니다.
이 강의에서는 MySQL 데이터베이스와 Flutter 애플리케이션을 모두 사용하는 방법을 살펴보고자 합니다. 우리는 단순히 PHP MySQL 서버에 대해 HTTP GET을 수행하고 데이터를 다운로드하고 이미지와 텍스트로 사용자 지정 목록 보기를 채웁니다. 그런 다음 목록 보기에서 단일 카드를 클릭하면 mysql에서 다운로드한 데이터를 전달하는 세부 정보 페이지가 열립니다.
데모
다음은 프로젝트에서 생성된 데모입니다.

비디오 튜토리얼
비디오 자습서는 다음과 같습니다.
1. PHP
먼저 다음과 같은 PHP 코드를 작성해야 합니다.
mysqli클래스를 사용하여 mysql 데이터베이스에 연결합니다.- mysql 데이터베이스 테이블에서 모든 레코드를 선택합니다.
- 결과를 PHP 배열로 반환합니다.
- 해당 배열을 JSON 인코딩하여 호출자에게 인쇄합니다.
(ㅏ). index.php
이것이 우리가 가진 유일한 파일입니다. 우리는 객체 지향 PHP 코드를 작성합니다. 이 파일의 첫 번째 단계는 데이터베이스 자격 증명을 포함할 Constants 클래스를 만드는 것입니다. MySQL에서 데이터베이스를 호스팅하므로 데이터베이스 이름, 사용자 이름 및 암호와 같은 자격 증명을 정의해야 합니다.
index.php 파일에서 여는 PHP 태그를 작성합니다.
<?php
그런 다음 정적 데이터베이스 자격 증명을 사용하여 클래스를 만듭니다.
class Constants
{
//DATABASE DETAILS
static $DB_SERVER="localhost";
static $DB_NAME="spacecraftsDB";
static $USERNAME="root";
static $PASSWORD="";
그런 다음 데이터베이스에서 모든 데이터를 선택하기 위한 sql 문을 정의합니다.
static $SQL_SELECT_ALL="SELECT * FROM spacecraftsTB";
}
동일한 php 파일에서 CRUD 메서드를 호스팅할 다른 클래스를 생성합니다.
class Spacecrafts
{
이 클래스에서는 mysqli를 사용하여 데이터베이스에 연결하는 함수를 정의합니다. 데이터베이스 서버, 데이터베이스 이름, 사용자 이름 및 암호를 mysqli 클래스의 생성자에 전달합니다. 그런 다음 연결이 불규칙하면 null을 반환하고 그렇지 않으면 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;
}
}
다음 함수를 사용하면 mysql 데이터베이스에서 데이터를 선택할 수 있습니다. 데이터베이스에서 데이터를 검색한 다음 해당 데이터를 배열로 푸시한 다음 해당 배열을 인코딩하고 인쇄합니다.
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.")));
}
}
다음은 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. 다트
다음 부분은 Dart 코드를 작성하는 것입니다. Dart는 Flutter 앱을 만드는 데 사용하는 프로그래밍 언어입니다. 하나의 파일만 있습니다.
(ㅏ). 메인 다트
가져오기를 추가하여 시작합니다.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' show get;
import 'dart:convert';
우주선을 나타내는 Spacecraft라는 클래스를 만듭니다. 이것은 우리의 모델 클래스입니다. 이 우주선의 속성을 이 클래스의 인스턴스로 정의합니다. 이 속성에는 ID, 이름, 이미지 URL 및 추진제가 포함됩니다.
class Spacecraft {
final String id;
final String name, imageUrl, propellant;
이러한 속성은 생성자를 통해 수신됩니다.
Spacecraft({
this.id,
this.name,
this.imageUrl,
this.propellant,
});
JSON 데이터를 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'],
);
}
}
또한 데이터를 나열할 화면을 만들어야 합니다. 데이터를 ListView에 나열합니다. 따라서 ListView 항목을 만들어야 합니다. 해당 ListView 항목을 클릭하면 세부 정보 페이지가 열리고 다른 화면에 결과가 표시됩니다.
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);
});
}
}
서버에서 JSON 데이터를 다운로드하는 방법에 관심이 있을 수 있습니다. 첫 번째 단계는 Future 객체를 반환하는 함수를 정의하는 것입니다. 이 메서드는 사용자 인터페이스 Thread를 차단하지 않도록 비동기식입니다. 이 함수의 일반 매개변수는 우주선 목록입니다.
Future<List<Spacecraft>> downloadJSON() async {
그런 다음 JSON 끝점을 정의합니다. 이것은 HTTP GET 요청을 수행할 URL입니다. 그런 다음 get() 함수를 사용하여 해당 엔드포인트를 실행합니다.
final jsonEndpoint =
"http://192.168.12.2/PHP/spacecrafts";
final response = await get(jsonEndpoint);
성공하면 응답 코드도 확인합니다. 응답 상태 코드 200은 성공을 의미하며 서버와 성공적으로 통신했습니다. 따라서 JSON 응답 본문을 목록으로 디코딩합니다. 목록 보기에서 렌더링할 목록은 다음과 같습니다.
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.');
}
전체 코드는 다음과 같습니다.
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
다운로드
다음은 참조 리소스입니다.
| 번호 | 위치 | 링크 |
|---|---|---|
| 1. | GitHub | 직접 다운로드 |
| 2. | GitHub | 찾아보기 |
| 3. | 유튜브 | 동영상 튜토리얼 |
| 4. | 유튜브 | 프로그래밍위자드 TV 채널 |
| 5. | 캄포샤 | Flutter 튜토리얼 모두 보기 |