Giter Site home page Giter Site logo

alexrabin / flutternativedraganddrop Goto Github PK

View Code? Open in Web Editor NEW
23.0 1.0 1.0 28.83 MB

A package that allows you to add native drag and drop support into your flutter app.

License: MIT License

Ruby 2.47% Swift 30.61% Objective-C 0.83% Dart 38.58% Java 27.50%
flutter ios drag-and-drop android drag-drop dropzone

flutternativedraganddrop's Introduction

native_drag_n_drop

native_drag_n_drop Donate Buy me a coffee GitHub issues GitHub Repo stars

A package that allows you to add native drag and drop support into your flutter app.

Like tutorials? Follow one along here iPadDropExample

Currently supported features

  • Support iPadOS 11, iOS 15, and Android 8.0 and above
  • Only has drop support (can drag data from outside of the app and drop into your flutter application)
  • Supports text, urls, images, videos, audio, pdfs, and custom file extensions
  • Can drop multiple items at once
  • Can add allowed number of items to be dragged at a time (iOS only. Android doesn't have this capability)

Usage

import 'package:native_drag_n_drop/native_drag_n_drop.dart';

List<DropData> receivedData = [];

@override
Widget build(BuildContext context) {
    return NativeDropView(
    allowedTotal: 5, //Allowed total only works on iOS (Android has limitations)
    allowedDropDataTypes: const [DropDataType.text, DropDataType.image, DropDataType.video],
    allowedDropFileExtensions: ['apk', 'dart'],
    receiveNonAllowedItems: false,
    child: receivedData.isNotEmpty
        ? ListView.builder(
            itemCount: receivedData.length,
            itemBuilder: (context, index) {
                var data = receivedData[index];
                if (data.type == DropDataType.text) {
                    return ListTile(
                    title: Text(data.dropText!),
                    );
                }

                return ListTile(
                    title: Text(data.dropFile!.path),
                );
            })
        : const Center(
            child: Text("Drop data here"),
        ),
    loading: (loading) {
        // display loading indicator / hide loading indicator
    },
    dataReceived: (List<DropData> data) {
        setState(() {
            receivedData.addAll(data);
        });
    });
}

The dataReceived callback returns List<DropData>.

enum DropDataType { text, url, image, video, audio, pdf, file}

class DropData {
  File? dropFile;
  String? dropText;
  Map<String, dynamic>? metadata;
  DropDataType type;
  DropData({this.dropFile, this.dropText, this.metadata, required this.type});
}

It is safe to assume that if the dataType is text or url then the dropText will be non null.

As for image, video, audio, pdf, file it is safe to assume the dropFile will be non null

All files are saved to the temp directory on the device so if you want to save the file to the device copy its data to a file in the documents directory.

Todo

  • specify the number of items allowed to be dropped at a time
  • Only allow certain data types
  • Android Support
  • Drag support (Dragging data within app to a source outside of flutter app)

flutternativedraganddrop's People

Contributors

alexrabin avatar getboolean avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

getboolean

flutternativedraganddrop's Issues

[Feature] Android Support

This issue will track android support's overall development. Individual features may get split into its own issue. Research on APIs and their implementation should also be posted here.

API

Android 7+

Android Drag and Drop API: https://developer.android.com/guide/topics/ui/drag-drop#DragPermissionsMultiWindow
Multi-Window guide: https://developer.android.com/guide/topics/large-screens/multi-window-support
Multi-Window/Multi-Instance: https://developer.samsung.com/galaxy-z/multi-window.html
DropHelper (min API level 24), simplified drag and drop: https://developer.android.com/guide/topics/ui/drag-drop#drophelper_for_simplified_drag_and_drop

Galaxy Fold, Z Fold2, or Z Fold3: https://developer.samsung.com/codelab/galaxy-z/multi-window-drag-drop.html
Emulator: https://developer.samsung.com/galaxy-z/testing.html

Surface Duo: https://docs.microsoft.com/en-us/dual-screen/android/sample-code/drag-drop?tabs=java
Emulator: https://docs.microsoft.com/en-us/dual-screen/android/emulator/surface-duo-download
Java SDK Examples: https://github.com/microsoft/surface-duo-sdk-samples
App Examples: https://github.com/microsoft/surface-duo-app-samples

Permissions

The following permissions are required for drag and drop in different scenarios: (info from here)

For public files, to use the media library MediaProvier, permissions for reading and writing external storage are required.

The FileProvider is used to share private app data. Use the per-URI permission mechanism for authorization. The source app can set Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION to grant the read or write permission to the Intent data or the URI specified in ClipData.

Features

  • NativeDropView (Drop Items Into App)
  • NativeDragView (Drag Items Outside App)
  • Allowed Data Types
  • Allowed File Extensions
  • Item Types
    • text
    • urls (Patterns.WEB_URL.matcher(url).matches())
    • images
    • videos
    • audio
    • pdfs
    • files
  • Change parameters during runtime

Other possible features

  • Callback to update UI according to result of drag events. This is all conceptual, implementation has not been decided yet but the idea is that the UI should be able to react to drag events.
    • ACTION_DRAG_STARTED: Drag started. Includes can/cannot accept, x/y location, and description of drag contents.
    • ACTION_DRAG_ENTERED: Drag entered NativeDropView's bounds. Includes can/cannot accept, and description of drag contents.
    • ACTION_DRAG_LOCATION: Drag is in NativeDropView's bounds and not in a child view that can accept. Includes x/y location.
    • ACTION_DRAG_EXITED: Drag moved out of NativeDropView's bounds or into a child view that can accept. Includes description of drag contents.
    • ACTION_DROP: Dragged contents dropped on NativeDropView and can accept and not in a child view that can accept the drop. Includes x/y location, and description of drag contents.
    • ACTION_DRAG_ENDED: Drag and drop session concluded. Includes if data was received and the x/y location of the drop in the view.
  • DraggableText (Tap and hold to drag entire text)
  • DraggableSelectableText (Tap and hold to select text, then tap and hold on selected text to drag)
  • DraggableImage

Some file types (apk) can't be dropped from Files' iCloud

I've run into the issue while testing that some filetypes can't be dropped from iCloud in the Files app, specifically apk. It works fine using Dropbox. This may not be limited to just apk files, I suspect its something related to iOS' Uniform Type Identifier system.

I'm not entirely sure of the reason, but theres two issues I've found related to iCloud. If DropDataType.file is enabled, apks cannot be dropped from iCloud unless "apk" is added to allowed file extensions. A second issue is that even when "apk" is added to the file extensions and it looks like it should accept, it does not load the file if dragged from iCloud.

In the first gif, you can see that the apk cannot be uploaded if it is on the iCloud drive, while it can if it is stored locally.

image

This second gif shows that other files work fine through iCloud

image

Able To Drop Non Allowed Items

Problem:
It is possible to drop items that have not been allowed as long as one item in the drop session is allowed

image

Proposed solution:
In the handle drop method, check the item if it conforms to an allowed type identifier or file extension. Code from the can drop method should be pulled into private functions so it can be reused (if possible).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.