#php #flutter #dart
#php #трепетание #dart
Вопрос:
у меня есть видео в (БАЗА ДАННЫХ MYSQL), и мне нужно отобразить его в flutter На самом деле я исследовал эту тему и не нашел полезного объяснения, так как я правильно загрузил видео в базу данных, и мне нужно отобразить его с помощью flutter, и я перепробовал много методов, но это не сработало итак, я проверяю код для серверной части, и он работает нормально, он возвращает данные в формате json без каких-либо проблем, но проблема в интерфейсе, я не знаю, как просмотреть его с помощью flutter, мне нужно отобразить его как youtube, проблема, которая мне кажется, такая, как показано на рисунке
я распечатал данные, поступающие из базы данных, и преобразовал их в данные json, и ничего плохого, как показано на рисунке
это код для серверной части
<?php
require_once("config.php");
require_once("class/video.php");
require_once("home.php");
require_once("class/VideoPlayer.php");
if (!isset($_GET["id"])) {
echo "No url passed into page";
exit();
}
$video = new Video($con, $_GET["id"], $userLoggedInObj);
$getId = $video->getId();
$getUploadedBy = $video->getUploadedBy();
$getTitle = $video->getTitle();
$getDescription = $video->getDescription();
$getPrivacy = $video->getPrivacy();
$getFilePath = $video->getFilePath();
$getCategory = $video->getCategory();
$getViews = $video->getViews();
$getDuration = $video->getDuration();
$incrementViews = $video->incrementViews();
echo json_encode(array('id' => $getId, 'uploadedBy' => $getUploadedBy, 'title' => $getTitle, 'description' => $getDescription, 'views' => $getViews, 'duration' => $getDuration, 'filePath' => $getFilePath));
?>
это код для класса VideoItem
class VideoItem {
final id;
final filePath;
final uploadedBy;
final title;
final description;
final views;
final duration;
VideoItem(
{this.id,
this.filePath,
this.uploadedBy,
this.title,
this.description,
this.views,
this.duration});
factory VideoItem.fromJson(Map<String, dynamic> jsonData) {
return VideoItem(
id: jsonData['id'],
filePath: jsonData['filePath'],
uploadedBy: jsonData['uploadedBy'],
title: jsonData['title'],
description: jsonData['description'],
views: jsonData['views'],
duration: jsonData['duration'],
);
}
}
это код для класса CustomListView
import 'package:flutter/material.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
import 'package:youtubeclone/pages/videodetails/videoitem.dart';
class CustomListView extends StatefulWidget {
final List<VideoItem> videoListView;
CustomListView({this.videoListView});
@override
_CustomListViewState createState() => _CustomListViewState();
}
class _CustomListViewState extends State<CustomListView> {
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: widget.videoListView.length,
itemBuilder: (context, int currentIndex) {
return createViewItem(widget.videoListView[currentIndex], context);
},
);
}
Widget createViewItem(VideoItem videoItem, BuildContext context) {
final List<YoutubePlayerController> _controllers =
[videoItem.id, videoItem.filePath]
.map<YoutubePlayerController>(
(videoId) => YoutubePlayerController(
initialVideoId: videoId,
flags: YoutubePlayerFlags(
autoPlay: false,
),
),
)
.toList();
return Padding(
padding: EdgeInsets.all(10),
child: Card(
elevation: 1.6,
child: Padding(
padding: EdgeInsets.all(5),
child: YoutubePlayer(
key: ObjectKey(videoItem.id),
controller: _controllers[0],
actionsPadding: EdgeInsets.only(left: 16.0),
bottomActions: [
CurrentPosition(),
SizedBox(width: 10.0),
ProgressBar(isExpanded: true),
SizedBox(width: 10.0),
RemainingDuration(),
FullScreenButton(),
],
),
),
),
);
}
}
это класс для наблюдения
import 'package:flutter/material.dart';
import 'package:youtubeclone/pages/componets/appbarallproject.dart';
import 'package:youtubeclone/pages/componets/mydrawer.dart';
import 'package:http/http.dart' show get;
import 'package:youtubeclone/pages/videodetails/customlistview.dart';
import 'dart:convert';
import 'videodetails/videoitem.dart';
class Watch extends StatefulWidget {
@override
_WatchState createState() => _WatchState();
}
class _WatchState extends State<Watch> {
GlobalKey<ScaffoldState> _drawerKey = GlobalKey();
VideoItem videoItem;
Future<List<VideoItem>> downloadJson() async {
//var data = {"id": videoItem.id, "filePath": videoItem.filePath};
final url = "http://10.0.2.2/videoTube/watch.php";
final response = await get(url);
if (response.statusCode == 200) {
List videoListItem = json.decode(response.body);
return videoListItem
.map((videoListItem) => new VideoItem.fromJson(videoListItem))
.toList();
} else {
throw Exception(
"we were not able to successfully download the json data");
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
key: _drawerKey,
drawer: MyDrawer(),
appBar: AppBarAllProject(drawerKey: _drawerKey),
body: Center(
child: FutureBuilder<List<VideoItem>>(
future: downloadJson(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<VideoItem> video = snapshot.data;
return CustomListView(
videoListView: video,
);
} else if (snapshot.hasData) {
return Text('${snapshot.error}');
}
//return CircularProgressIndicator();
},
),
),
),
);
}
}
Ответ №1:
Внутри ваших FutureBuilder
операторов if else не охватывает все возможные результаты. FutureBuilder
всегда должен возвращать виджет. С помощью этого кода вы сможете увидеть сообщение об ошибке и исправить свой код в будущем.
if (snapshot.hasData) {
List<VideoItem> video = snapshot.data;
return CustomListView(
videoListView: video,
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
} else {
return Text('Unknown condition');
}
Комментарии:
1. я получил эту ошибку ((((NoSuchMethodError: идентификатор получателя был вызван в null. Получатель: null Пытался вызвать: id))))
2. @MuhammedJack Спасибо тебе. Я скоро отредактирую свой ответ!
Ответ №2:
В вашем PHP-коде вы отображаете только один объект, но ожидаете список объектов в Flutter. Вы должны настроить свой код Flutter так, чтобы он принимал один объект. Вот так:
if (response.statusCode == 200) {
Map videoListItem = json.decode(response.body);
return videoListItem = VideoItem.fromJson(videoListItem);
}
Комментарии:
1. выдает мне эту ошибку (((Значение типа ‘VideoItem’ не может быть присвоено переменной типа ‘Map<динамический, динамический>’. Попробуйте изменить тип переменной или привести правый тип к ‘Map<dynamic, dynamic>’))) поэтому я привел его к (((возвращает videoListItem = VideoItem.FromJSON(videoListItem) как Map;))
2. и выдает мне другую ошибку (((Значение типа ‘Map<dynamic, dynamic>’ не может быть возвращено из метода ‘downloadJson’, потому что он имеет возвращаемый тип ‘Future<List<VideoItem>>’)))
3. @MuhammedJack Прав. Там будет несколько мест, которые вам придется исправить. Вместо списка VideoListItem у вас есть один элемент списка. Вам придется соответствующим образом обновить свой код.