Daniyal Haider
Daniyal Haider

Reputation: 33

how to make material widget draggable into a container and score them in flutter?

i want to make either alphabets, pictures and some material button draggable in flutter like user can drag those on the screen. i am trying but it isnt working. i made the alphabet draggable but the code itself is too complicated to work with. i want when a user drags a material widget or an alphabet or the pictures be able to drop it in a container i specified. Also the alphabets are showing in half like the are cut in between. i will be very thankfull if someone helps me.

import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter_tts/flutter_tts.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';

import '../../../constants.dart';
import '../../../utils/routes.dart';

class DragDrop extends StatefulWidget {
  const DragDrop({Key? key}) : super(key: key);

  @override
  State<DragDrop> createState() => _DragDropState();
}

final FlutterTts flutterTts = FlutterTts();
final List words = ["h", "c", "d", "w", "c", "f"];
moveToQ2(BuildContext context) async {
  changeButton = true;
  await Navigator.pushNamed(context, MyRoutes.speakQ);
}

String question =
    "Listen to this letter sound and then drag all  the letter whose sound you hear into the bucket.";
var changeButton = false;
final Map<String, bool> score = {};
var word_1 = "";

final Map choices = {
  'A': Colors.green,
};

speak(word) async {
  await flutterTts.setLanguage("en-US");
  await flutterTts.setPitch(1);
  await flutterTts.setVolume(1.0);
  await flutterTts.speak(word);
}

int seed = 0;

class _DragDropState extends State<DragDrop> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: true,
        backgroundColor: Colors.cyan,
        // ignore: prefer_const_constructors
        title: Text("AD&DY"),
      ),
      body: Padding(
          padding: const EdgeInsets.all(14.0),
          // ignore: prefer_const_literals_to_create_immutables
          child: SingleChildScrollView(
              child: SafeArea(
            child: Column(children: [
              Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                const Padding(
                  padding: EdgeInsets.symmetric(horizontal: kDefaultPadding),
                  //child: ProgressBar(),
                ),
                const Padding(
                  padding: EdgeInsets.symmetric(horizontal: kDefaultPadding),
                  child: Text.rich(
                    TextSpan(
                      text: "Question 1",
                      style: TextStyle(
                        fontSize: 24,
                      ),
                      children: [TextSpan(text: "/25")],
                    ),
                  ),
                ),
                const SizedBox(
                  height: 20,
                ),
                const Divider(
                  thickness: 1.5,
                ),
                Text.rich(
                  TextSpan(
                    text: question,
                    style: const TextStyle(
                      fontSize: 15,
                    ),
                  ),
                ),
                const SizedBox(
                  height: 20,
                ),
                ListTile(
                  onTap: () {
                    word_1 = (words.toList()..shuffle()).first;
                    speak(word_1);
                  },
                  leading: const Icon(CupertinoIcons.play_circle,
                      color: Colors.black),
                  title: const Text("Play",
                      textScaleFactor: 1.2,
                      style: TextStyle(
                        color: Colors.black,
                      )),
                ),
                const SizedBox(
                  height: 20,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: choices.keys
                      .map((words) => _buildDragTarget(words))
                      .toList()
                    ..shuffle(Random(seed)),
                ),
                const SizedBox(
                  height: 20,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: words.map((emoji) {
                    return Draggable<String>(
                      data: emoji,
                      child: Emoji(words: score[emoji] == true ? '✅' : emoji),
                      feedback: Emoji(words: emoji),
                      childWhenDragging: const Emoji(words: ''),
                    );
                  }).toList(),
                ),
                Material(
                  color: Color.fromARGB(255, 174, 145, 224),
                  borderRadius: BorderRadius.circular(changeButton ? 50 : 8),
                  child: InkWell(
                    onTap: () => moveToQ2(context),
                    child: AnimatedContainer(
                      duration: Duration(seconds: 1),
                      width: changeButton ? 50 : 150,
                      height: 50,
                      alignment: Alignment.center,
                      child: changeButton
                          ? Icon(
                              Icons.done,
                              color: Colors.black,
                            )
                          : Text(
                              'Next',
                              style: TextStyle(
                                  color: Colors.black,
                                  fontWeight: FontWeight.bold,
                                  fontSize: 18),
                            ),
                    ),
                  ),
                ),
              ]),
            ]),
          ))),
    );
  }
}

Widget _buildDragTarget(emoji) {
  return DragTarget<String>(
    builder: (BuildContext context, List<String?> incoming, List rejected) {
      if (score[emoji] == true) {
        return Container(
          color: Colors.white,
          child: const Text('Correct!'),
          alignment: Alignment.center,
          height: 80,
          width: 200,
        );
      } else {
        return Container(color: choices[emoji], height: 80, width: 200);
      }
    },
    onWillAccept: (data) => data == emoji,
    onLeave: (data) {},
  );
}

class Emoji extends StatelessWidget {
  const Emoji({Key? key, required this.words}) : super(key: key);

  final String words;

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.transparent,
      child: Container(
        alignment: Alignment.center,
        height: 50,
        padding: const EdgeInsets.all(10),
        child: Text(
          words,
          style: const TextStyle(color: Colors.black, fontSize: 50),
        ),
      ),
    );
  }
}

final plyr = AudioPlayer();

Upvotes: 0

Views: 807

Answers (1)

Bashar
Bashar

Reputation: 214

You Need A Better State Management Your Code is Barely Readable You Can Try Riverpod Or Bloc To Make The Task Easer, Plus Why Not Inherit from Flutter Own Draggable And Drag Target, The Following Link Contains Simpler Approach, Hope This Helped Flutter Draggable And Drag Target

Upvotes: 2

Related Questions