More
ドラッグアンドドロップのFlutterアプリをドラッグ可能なウィジェットとBack4Appで構築する
22 分
はじめに インタラクティブなドラッグアンドドロップインターフェースは、ユーザーがui要素を直感的に操作できるようにすることで、ユーザーエクスペリエンスを向上させます。flutterは、こうしたインタラクションを作成するための draggable と dragtarget ウィジェットを提供します。このチュートリアルでは、 draggable ウィジェットを使用してリスト間でアイテムを移動させ、parse serverによって提供されるバックエンドサービスであるback4appを使用してデータの永続性を持たせるflutterアプリケーションの構築方法を学びます。 このチュートリアルの終わりまでに、ユーザーがアイテムを1つのリストから別のリストにドラッグできる機能的なflutterアプリを持つことができ、変更はback4appから保存され、取得されます。このチュートリアルは、すべての経験レベルのflutter開発者に適しています。 前提条件 このチュートリアルを完了するには、次のものが必要です flutter sdk があなたのマシンにインストールされていること。あなたのオペレーティングシステムに対する 公式flutterインストールガイド https //flutter dev/docs/get started/install を参照してください。 flutterとdartの基本的な知識 。flutterが初めての場合は、 flutterドキュメント https //flutter dev/docs を確認して基本を理解してください。 ideまたはテキストエディタ (visual studio codeやandroid studioなど)。 バック4アプリのアカウント 。 back4app https //www back4app com/ で無料アカウントにサインアップしてください。 flutter用のparse server sdk をプロジェクトに追加します。 back4app flutter sdkガイド https //www back4app com/docs/flutter/parse flutter sdk を参照して設定方法を学びます。 概要 タスクを「やること」リストから「完了」リストにドラッグできるタスク管理アプリを構築します。このアプリは タスクのドラッグを有効にするために draggable ウィジェットを使用します。 ドロップゾーンを定義するために dragtarget ウィジェットを使用します。 データを永続化するために back4app からタスクを保存および取得します。 ステップ 1 – flutter プロジェクトの設定 1 1 新しい flutter プロジェクトを作成する ターミナルを開いて、次のコマンドを実行します flutter create drag drop app プロジェクトディレクトリに移動します cd drag drop app 1 2 依存関係を追加する 「 pubspec yaml 」を開いて、次の依存関係を追加します dependencies flutter sdk flutter parse server sdk flutter ^4 0 1 「 flutter pub get 」を実行して、パッケージをインストールします。 ステップ 2 – back4appの設定 2 1 新しいback4appアプリケーションを作成する あなたの back4appダッシュボード https //dashboard back4app com/ にログインします。 「 新しいアプリを作成する 」をクリックします。 アプリケーションの名前を入力します。例 「dragdropapp」 , そして「 作成 」をクリックします。 2 2 データモデルの設定 アプリケーションダッシュボードで、 "データベース" セクションに移動します。 "クラスを作成" をクリックします。 モーダルで "カスタム" を選択します。 クラス名として "タスク" を入力します。 "クラスを作成" をクリックします。 2 3 クラスにカラムを追加 "タスク" クラスで、 "+" をクリックして新しいカラムを追加します。 次のカラムを追加します タイトル タイプ 文字列 ステータス タイプ 文字列 "タスク" クラスにサンプルデータを追加します。例えば 2 4 アプリケーションの認証情報を取得 アプリ設定 > セキュリティとキー に移動します。 あなたの アプリケーションid と クライアントキー をメモします。 ステップ3 – flutterアプリでparseを初期化 開く lib/main dart そして次のように修正します import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'screens/home page dart'; // you'll create this file next void main() async { widgetsflutterbinding ensureinitialized(); const keyapplicationid = 'your application id'; const keyclientkey = 'your client key'; const keyparseserverurl = 'https //parseapi back4app com'; await parse() initialize( keyapplicationid, keyparseserverurl, clientkey keyclientkey, debug true, ); runapp(myapp()); } class myapp extends statelesswidget { @override widget build(buildcontext context) { return materialapp( title 'drag and drop app', theme themedata( primaryswatch colors blue, ), home homepage(), ); } } 置き換える 'your application id' と 'your client key' を実際のback4appの資格情報に置き換えます。 ステップ4 – タスクモデルの作成 新しいディレクトリを作成します models の下に lib そして task dart という名前のファイルを追加します // lib/models/task dart class task { string id; string title; string status; task({required this id, required this title, required this status}); } ステップ5 – back4appからタスクを取得する 新しいディレクトリを作成します services の下に lib そして task service dart という名前のファイルを追加します // lib/services/task service dart import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/task dart'; class taskservice { future\<list\<task>> gettasksbystatus(string status) async { final querybuilder\<parseobject> query = querybuilder\<parseobject>(parseobject('task')) whereequalto('status', status); final parseresponse apiresponse = await query query(); if (apiresponse success && apiresponse results != null) { return apiresponse results! map((data) { return task( id data objectid!, title data get\<string>('title') ?? '', status data get\<string>('status') ?? '', ); }) tolist(); } else { return \[]; } } future\<void> updatetaskstatus(string id, string status) async { var task = parseobject('task') objectid = id set('status', status); await task save(); } } ステップ 6 – draggable と dragtarget を使った ui の構築 新しいディレクトリを作成します screens を lib の下に作成し、次の名前のファイルを追加します home page dart // lib/screens/home page dart import 'package\ flutter/material dart'; import ' /models/task dart'; import ' /services/task service dart'; class homepage extends statefulwidget { @override homepagestate createstate() => homepagestate(); } class homepagestate extends state\<homepage> { final taskservice taskservice = taskservice(); list\<task> todotasks = \[]; list\<task> completedtasks = \[]; @override void initstate() { super initstate(); fetchtasks(); } future\<void> fetchtasks() async { var todo = await taskservice gettasksbystatus('to do'); var completed = await taskservice gettasksbystatus('completed'); setstate(() { todotasks = todo; completedtasks = completed; }); } void ondragaccept(task task, string newstatus) async { await taskservice updatetaskstatus(task id, newstatus); await fetchtasks(); } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('drag and drop tasks'), ), body row( children \[ expanded( child taskcolumn( title 'to do', tasks todotasks, ondragaccept (task) => ondragaccept(task, 'to do'), ), ), expanded( child taskcolumn( title 'completed', tasks completedtasks, ondragaccept (task) => ondragaccept(task, 'completed'), ), ), ], ), ); } } class taskcolumn extends statelesswidget { final string title; final list\<task> tasks; final function(task) ondragaccept; taskcolumn({ required this title, required this tasks, required this ondragaccept, }); @override widget build(buildcontext context) { return dragtarget\<task>( onwillaccept (task) => true, onaccept (task) { ondragaccept(task); }, builder (context, candidatedata, rejecteddata) { return container( padding edgeinsets all(16 0), child column( children \[ text( title, style textstyle(fontsize 22, fontweight fontweight bold), ), expanded( child listview( children tasks map((task) { return draggable\<task>( data task, feedback material( child taskcard(task task), elevation 4 0, ), childwhendragging opacity( opacity 0 5, child taskcard(task task), ), child taskcard(task task), ); }) tolist(), ), ), ], ), ); }, ); } } class taskcard extends statelesswidget { final task task; taskcard({required this task}); @override widget build(buildcontext context) { return card( margin edgeinsets symmetric(vertical 8 0), child listtile( title text(task title), ), ); } } 説明 ホームページ "to do" と "completed" タスクの2つの列を表示するメイン画面です。 タスク列 タスクを表示し、 ドラッグターゲット として機能するウィジェットです。 ドラッグ可能 なタスクのための。 タスクカード 個々のタスク情報を表示するウィジェットです。 ステップ7 – アプリの実行 7 1 アプリを実行する ターミナルで実行します flutter run 7 2 ドラッグアンドドロップ機能のテスト 「to do」列からタスクをドラッグして「completed」列にドロップします。 タスクのステータスが更新され、「completed」の下に表示されるはずです。 変更はback4appに持続します。アプリを再起動しても、タスクは新しいステータスのままです。 結論 このチュートリアルでは、flutterアプリケーションでドラッグアンドドロップ機能を実装する方法を学びました。 draggable と dragtarget ウィジェットを使用しました。タスクデータを保存および取得するためにback4appを統合し、セッション間でデータの持続性を実現しました。このインタラクティブなアプリは、直感的なui要素とスケーラブルなバックエンドを使用してユーザーエクスペリエンスを向上させる方法を示しています。 重要なポイント ドラッグ可能なウィジェット ユーザーがui要素をドラッグできるようにします。 ドラッグターゲットウィジェット ドラッグ可能なアイテムのドロップゾーンを定義します。 back4app統合 データを保存および管理するためのバックエンドを提供します。 次のステップ 認証の追加 ユーザー認証を実装して、個別のタスクリストを持つようにします。 ui/uxの向上 アニメーション、カスタムアイコン、改善されたレイアウトを追加します。 リアルタイム更新 back4appのライブクエリを使用して、複数のデバイスでタスクをリアルタイムで更新します。 エラーハンドリング ネットワークの問題やデータの競合に対するエラーハンドリングを実装します。 追加リソース back4appドキュメント https //www back4app com/docs flutter用parse sdkガイド https //docs parseplatform org/flutter/guide/ flutter公式ドキュメント https //flutter dev/docs ドラッグ可能ウィジェット https //api flutter dev/flutter/widgets/draggable class html ドラッグターゲットウィジェット https //api flutter dev/flutter/widgets/dragtarget class html 楽しいコーディングを!