14_flutter_视频播放,代码生成,拖动UI元素

811 阅读4分钟

1_视频播放


1.1_集成到应用里面

pubspec.yaml

  chewie: ^0.12.2
  video_player: ^1.0.1
  assets:
   - videos/IntroVideo.mp4

android/app/src/main/AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>
android:usesCleartextTraffic="true"

chewie_list_item.dart

import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

class ChewieListItem extends StatefulWidget {
  // This will contain the URL/asset path which we want to play
  final VideoPlayerController videoPlayerController;
  final bool looping;

  ChewieListItem({
    @required this.videoPlayerController,
    this.looping,
    Key key,
  }) : super(key: key);

  @override
  _ChewieListItemState createState() => _ChewieListItemState();
}

class _ChewieListItemState extends State<ChewieListItem> {
  ChewieController _chewieController;

  @override
  void initState() {
    super.initState();
    // Wrapper on top of the videoPlayerController
    _chewieController = ChewieController(
      videoPlayerController: widget.videoPlayerController,
      aspectRatio: 16 / 9,
      // Prepare the video to be played and display the first frame
      autoInitialize: true,
      looping: widget.looping,
      // Errors can occur for example when trying to play a video
      // from a non-existent URL
      errorBuilder: (context, errorMessage) {
        return Center(
          child: Text(
            errorMessage,
            style: TextStyle(color: Colors.white),
          ),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Chewie(
        controller: _chewieController,
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    // IMPORTANT to dispose of all the used resources
    widget.videoPlayerController.dispose();
    _chewieController.dispose();
  }
}

main.dart

import 'package:flutter_app/chewie_list_item.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Video Player'),
      ),
      body: ListView(
        children: <Widget>[
          ChewieListItem(
            videoPlayerController: VideoPlayerController.asset(
              'videos/IntroVideo.mp4',
            ),
            looping: true,
          ),
        ],
      ),
    );
  }
}

效果

2_代码生成

2.1_代码生成复制

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return  const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: '代码生成',
      home: HomePage(),
    );
  }
}

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

  @override
  HomePageState createState() => HomePageState();
}

class HomePageState extends State<HomePage> {
  final TextEditingController _textController = TextEditingController();

  late String dropdownValue=parameterstring.first;
  late String dropdownValue1=parameterstring1.first;

  List <String> parameterstring=['GPIO_NUM_0','GPIO_NUM_1','GPIO_NUM_2','GPIO_NUM_3'];
  List <String> parameterstring1=['GPIO_MODE_OUTPUT','GPIO_MODE_INPUT'];

  // This function is triggered when the copy icon is pressed
  Future<void> _copyToClipboard() async {
    _textController.text =codestring();
    await Clipboard.setData(ClipboardData(text: _textController.text));
    if (!mounted) return;
    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
      content: Text('代码复制成功!'),
    ));
  }

  String codestring(){
    String codestring;
    codestring=templateString1('gpio_pad_select_gpio',dropdownValue)+
               templateString1('gpio_set_direction',dropdownValue1);

     return codestring;
  }

  String templateString1(String functionName,String parameter1){
    String fullFunctionString;
    fullFunctionString='$functionName($parameter1);\n';
    
    return fullFunctionString;
}

DropdownButton<String> buildDropdown({
  required final String? selectedValue,
  required final ValueSetter<String?> onSelected,
  required final List<String> data,
}) {
  return DropdownButton(
    value: selectedValue,
    items: data.map<DropdownMenuItem<String>>((String value) {
      return DropdownMenuItem(
        value: value,
        child: Text(value),
      );
    }).toList(),
    onChanged: (String? newValue) {
      onSelected(newValue);
    },
  );
}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('代码生成'),
          backgroundColor: Colors.deepOrange,
        ),
        body:Center(
          child:Column(
          children: <Widget>[
            const Text('选择GPIO'),
            buildDropdown(
              selectedValue:dropdownValue,
              onSelected: (v) => setState(() {
              dropdownValue = v!;}),
              data: parameterstring,
            ),
            const Text('输出还是输入'),
            buildDropdown(
              selectedValue:dropdownValue1,
              onSelected: (v) => setState(() {
              dropdownValue1 = v!;}),
              data: parameterstring1,
            ),
            TextField(
              maxLines: null, //可以多行
              controller: _textController,
              decoration: InputDecoration(
                icon: IconButton(
                  icon: const Icon(Icons.copy),
                  onPressed: _copyToClipboard,
                ),
              ),
            ),
          ],
        )));
  }
}

3_拖动UI元素


3.1_自由拖放图片

main.dart

import "package:flutter/material.dart";
import "drag.dart";

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: Scaffold(body: HomePage()));
  }
}

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

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: const <Widget>[
        //拖动组件
        Drag(offset: Offset(80, 80), image: "Breadboard.jpg"),
        Drag(offset: Offset(580, 80), image: "LCD_IPS_1_3.png"),
        Center(),
      ],
    );
  }
}

drag.dart

import "package:flutter/material.dart";

class Drag extends StatefulWidget {
  const Drag({Key? key, required this.offset, required this.image})
      : super(key: key);
  final Offset offset;
  final String image;
  @override
  _DragState createState() => _DragState();
}

class _DragState extends State<Drag> {
  late Offset position;

  @override
  void initState() {
    super.initState();
    position = widget.offset;
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: position.dx,
      top: position.dy,
      child: Draggable<String>(
        data: widget.image,
        feedback: Center(
          child: Image.asset('lib/images/' + widget.image),
        ),
        childWhenDragging: Opacity(
          opacity: .3,
          child: Center(
            child: Image.asset('lib/images/' + widget.image),
          ),
        ),
        onDragEnd: (details) => setState(() => position = details.offset),
        child: Container(
          alignment: Alignment.topCenter,
          child: Center(
            child: Image.asset('lib/images/' + widget.image),
          ),
        ),
      ),
    );
  }
}

2022-02-07 15-30-26屏幕截图.png

3.2_自由拖放

main.dart

import "package:flutter/material.dart";
import "drag.dart";

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: Scaffold(body: HomePage()));
  }
}

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

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: const <Widget>[
        //拖动组件
        Drag(
          offset: Offset(80, 80),
        ),
        Drag(
          offset: Offset(580, 80),
        ),
        Center(),
      ],
    );
  }
}

drag.dart

import "package:flutter/material.dart";

class Drag extends StatefulWidget {
  const Drag({Key? key, required this.offset}) : super(key: key);
  final Offset offset;

  @override
  _DragState createState() => _DragState();
}

class _DragState extends State<Drag> {
  late Offset position;

  @override
  void initState() {
    super.initState();
    position = widget.offset;
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: position.dx,
      top: position.dy,
      child: Draggable(
        feedback: Center(
          child: Container(
              width: 300,
              height: 400,
              margin: const EdgeInsets.all(15.0),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(5),
                color: Colors.blue,
              ),
              child: CustomPaint(
                painter: OpenPainter(),
              )),
        ),
        childWhenDragging: Opacity(
          opacity: .3,
          child: Container(
              width: 300,
              height: 400,
              margin: const EdgeInsets.all(15.0),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(5),
                color: Colors.blue,
              ),
              child: CustomPaint(
                painter: OpenPainter(),
              )),
        ),
        onDragEnd: (details) => setState(() => position = details.offset),
        child: Container(
            width: 300,
            height: 400,
            margin: const EdgeInsets.all(15.0),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(5),
              color: Colors.blue,
            ),
            child: CustomPaint(
              painter: OpenPainter(),
            )),
      ),
    );
  }
}

class OpenPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    var paint1 = Paint()
      ..color = const Color(0xff995588)
      ..style = PaintingStyle.fill;
    canvas.drawRRect(
        RRect.fromLTRBR(50, 50, 250, 350, const Radius.circular(10)), paint1);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

Peek 2022-02-15 19-01.gif

3.3_拖放放置固定位置

main.dart

import "package:flutter/material.dart";
import 'gridpositioning.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: Scaffold(body: HomePage()));
  }
}

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

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: const <Widget>[
        //拖动组件
        GridPositioning(numberoflines: 5, total: 15,initializelocation: 3),
        Center(),
      ],
    );
  }
}

gridpositioning.dart

import "package:flutter/material.dart";

class GridPositioning extends StatefulWidget {
  const GridPositioning(
      {Key? key,
      required this.numberoflines,
      required this.total,
      required this.initializelocation})
      : super(key: key);
  final int numberoflines;
  final int total;
  final int initializelocation;
  @override
  GridPositioningState createState() => GridPositioningState();
}

class GridPositioningState extends State<GridPositioning> {
  late int _indexOfDroppedItem = widget.initializelocation;
  bool _isDragging = false;

  void _acceptDraggedItem(int index) {
    setState(() {
      _indexOfDroppedItem = index;
    });
  }

  void _setIsDragging() {
    setState(() {
      _isDragging = true;
    });
  }

  void _resetIsDragging() {
    setState(() {
      _isDragging = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: GridView.count(
        shrinkWrap: true,
        primary: false,
        crossAxisCount: widget.numberoflines,
        children: List.generate(widget.total, (index) {
          return Padding(
            padding: const EdgeInsets.all(44.0),
            child: index == _indexOfDroppedItem
                ? Draggable<int>(
                    data: index,
                    child: Container(
                      decoration: BoxDecoration(
                          color: Colors.blue,
                          border: Border.all(
                            color: Colors.blue,
                          ),
                          borderRadius:
                              const BorderRadius.all(Radius.circular(10))),
                    ),
                    childWhenDragging: Container(
                      decoration: BoxDecoration(
                          border: Border.all(
                            color: Colors.blue,
                          ),
                          borderRadius:
                              const BorderRadius.all(Radius.circular(20))),
                    ),
                    onDragStarted: () {
                      _setIsDragging();
                    },
                    onDraggableCanceled: (_, __) {
                      _resetIsDragging();
                    },
                    onDragCompleted: () {
                      _resetIsDragging();
                    },
                    feedback: Container(
                      width: 100,
                      height: 100,
                      decoration: const BoxDecoration(
                          color: Colors.blue,
                          borderRadius: BorderRadius.all(Radius.circular(20))),
                    ),
                  )
                : DragTarget<int>(
                    builder: (
                      BuildContext context,
                      List<dynamic> accepted,
                      List<dynamic> rejected,
                    ) {
                      return Container(
                          decoration: BoxDecoration(
                        border: Border.all(
                          color: Colors.blue,
                        ),
                        borderRadius: BorderRadius.all(_isDragging
                            ? const Radius.circular(20)
                            : const Radius.circular(10)),
                      ));
                    },
                    onAccept: (int data) {
                      _acceptDraggedItem(index);
                    },
                  ),
          );
        }),
      ),
    );
  }
}

Peek 2022-02-15 15-00.gif

3.4_传递数据

main.dart

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: Scaffold(body: HomePage()));
  }
}

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

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: const <Widget>[
        //拖动组件
        DragTargetWidget(),
      ],
    );
  }
}

breadboard.dart

import 'package:flutter/material.dart';

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

  @override
  _DragTargetWidgetState createState() => _DragTargetWidgetState();
}

class _DragTargetWidgetState extends State<DragTargetWidget> {
  Color caughtColor = Colors.red;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        const DragBox(
          Offset(0.0, 0.0),
          'Box 1',
          Colors.purple,
        ),
        const DragBox(
          Offset(200.0, 0.0),
          'Box 2',
          Colors.orange,
        ),
        const DragBox(
          Offset(300.0, 0.0),
          'Box 3',
          Colors.lightGreen,
        ),
        Positioned(
          left: 100.0,
          bottom: 0.0,
          child: DragTarget(
            onAccept: (Color color) {
              caughtColor = color;
            },
            builder: (
              BuildContext context,
              List<dynamic> accepted,
              List<dynamic> rejected,
            ) {
              return Container(
                width: 200.0,
                height: 200.0,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(28.0),
                  color: accepted.isEmpty ? caughtColor : Colors.grey.shade200,
                ),
                child: const Center(
                  child: Text("Drag Here!"),
                ),
              );
            },
          ),
        )
      ],
    );
  }
}

class DragBox extends StatefulWidget {
  final Offset initPos;
  final String label;
  final Color itemColor;

  const DragBox(this.initPos, this.label, this.itemColor, {Key? key})
      : super(key: key);

  @override
  DragBoxState createState() => DragBoxState();
}

class DragBoxState extends State<DragBox> {
  Offset position = const Offset(0.0, 0.0);

  @override
  void initState() {
    super.initState();
    position = widget.initPos;
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: position.dx,
      top: position.dy,
      child: Draggable(
        data: widget.itemColor,
        child: Container(
          width: 100.0,
          height: 100.0,
          color: widget.itemColor,
          child: Center(
            child: Text(
              widget.label,
              style: const TextStyle(
                color: Colors.white,
                decoration: TextDecoration.none,
                fontSize: 20.0,
              ),
            ),
          ),
        ),
        onDraggableCanceled: (velocity, offset) {
          setState(() {
            position = offset;
          });
        },
        feedback: Container(
          width: 120.0,
          height: 120.0,
          color: widget.itemColor.withOpacity(0.5),
          child: Center(
            child: Text(
              widget.label,
              style: const TextStyle(
                color: Colors.white,
                decoration: TextDecoration.none,
                fontSize: 18.0,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Peek 2022-02-13 17-32.gif