2

問題

Flutter を使用して並べ替えビジュアライザーを構築しようとしています。を使用してCustomPainter、ソートする整数リストの値に対応する垂直線を描画しました。アプリケーションは、ユーザーが [バブル ソート] オプションをクリックするとDropDownButton (後でソート アルゴリズムを追加する予定です)、CustomPainterキャンバスの垂直線が自動的にソートされるように設定されています。

コード

import 'dart:io';
import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

void main() => runApp(HomePage());

class HomePage extends StatefulWidget {
  @override
  HomePageSate createState() {
    return HomePageState();
  }
}

class HomePageState extends State<HomePage> {
  List<int> arr;

  @override
  void initState() {
    super.initState();
    arr = _getRandomIntegerList();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Sorting Visualiser'),
          actions: <Widget>[
            DropdownButton<String>(
              onChanged: (dynamic choice) {
                switch (choice) {
                  case 'Bubble Sort':
                    _bubbleSortVisualiser();
                    break;
                }
              },
              items: <String>['Bubble Sort']
                  .map<DropdownMenuItem<String>>((String value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: Text(value),
                );
              }).toList(),
            )
          ],
        ),
        //The following flatButton refreshes arr to have a new array of random integers.
        bottomNavigationBar: FlatButton(
          onPressed: () {
            setState(() {
              arr = _getRandomIntegerList();
            });
          },
          child: Icon(Icons.refresh),
        ),
        body: CustomPaint(
          size: Size(double.infinity, double.infinity),
          painter: SortingCanvas(arr),
        ),
      ),
    );
  }

  //function to sort the list using bubble sort and repaint the canvas at every iteration.
  void _bubbleSortVisualiser() {
    print('Bubble sort function called');
    List<int> bubbleArr = List.from(arr);

    for (int i = 0; i < bubbleArr.length - 1; i++) {
      for (int j = 0; j < bubbleArr.length - 1 - i; j++) {
        int temp;
        if (bubbleArr[j] < bubbleArr[j + 1]) {
          temp = bubbleArr[j];
          bubbleArr[j] = bubbleArr[j + 1];
          bubbleArr[j + 1] = temp;
          //Every time arr changes setState() is called to visualise the changing array.
          setState(() {
            arr = List.from(bubbleArr);
            print("Updated to : $arr");
          });

          //Sleep is called so that the change is noticeable
          sleep(Duration(seconds: 1));

        }
      }
    }
  }
}

class SortingCanvas extends CustomPainter {
  List<int> arr;

  SortingCanvas(this.arr);

  @override
  void paint(Canvas canvas, Size size) {
    var linePaint = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.stroke
      ..strokeWidth = 5.0
      ..isAntiAlias = true;
    //IMP the first offset is the bottom point and the second is the top point of the vertical line. 
    //It is offset from the top left corner of the canvas
    for (int i = 1; i <= arr.length; i++) {
      canvas.drawLine(Offset(50.0 + (20 * i), size.height - 50),
          Offset(50.0 + (20 * i), 50.0 * arr[i - 1]), linePaint);
    }
  }

  @override
  bool shouldRepaint(SortingCanvas oldDelegate) {
    return !listEquals(this.arr, oldDelegate.arr);
  }
}

//Helper function to get a list of 10 random integers
List<int> _getRandomIntegerList() {
  List<int> arr = [];
  Random rng = new Random();

  for (int i = 0; i < 10; i++) {
    arr.add(rng.nextInt(10));
  }
  return arr;
}

ただし、最終的にソートされたものだけがarrキャンバスに視覚化され、何らかの理由ですべての中間ステップがスキップされます。しかし、ログはリストの更新を示しています。

スクリーンショット

ランダムリストの初期画面 ドロップダウンボタン のバブルソートをクリック ソートされたリスト

このsleep()機能はアニメーションをエミュレートするためだけに追加されたものであり、この問題が解決されたら、適切なアニメーションに置き換える予定です。また、アプリケーションが少し醜いことは承知していますが、UI を磨く前にロジックを正しく取得したいと考えています。

4

2 に答える 2

0

この行:

class HomePageState extends State<StatefulWidget> {

する必要があります

class HomePageState extends State<HomePage> {

それで全部です。それでうまくいくはずです。

また、これを変更する必要があります。

  @override
  State<StatefulWidget> createState() {
    return HomePageState();
  }

に:

  @override
  State<HomePage> createState() => HomePageState();
于 2019-12-08T15:25:24.063 に答える