패키지, 저장소 및 앱 카테고리 검색

패키지 상세v1.0.8

drag_and_drop_gridview

드래그 앤 드롭 GridView는 Flutter의 GridView 위젯의 기능을 확장하여 드래그 앤 드롭으로 GridViewItem을 간편하게 재정렬할 수 있는 자유를 제공합니다.

30일 다운로드
81
좋아요
99
Pub 점수
40

패키지 설치

flutter pub add drag_and_drop_gridview

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

Drag And Drop GridView는 표준 GridView 위젯을 향상시켜 그리드 항목의 직관적인 드래그 앤 드롭 재정렬 기능을 제공하는 Flutter 패키지입니다. 복잡한 사용자 정의 로직 없이 그리드 레이아웃 내 요소를 재정렬하는 과정을 간소화합니다. 작업 보드, 이미지 갤러리 또는 사용자 정의 대시보드와 같은 상호작용적이고 사용자 중심의 항목 정렬이 필요한 애플리케이션에 적합합니다. 기존 Flutter 프로젝트와 원활하게 통합되며 부드럽고 반응성 있는 인터랙션을 지원합니다.

사용 사례

  • 앱에서 재정렬 가능한 항목 목록
  • 사용자 정의 가능한 대시보드 레이아웃
  • 인터랙티브 이미지 또는 콘텐츠 그리드
  • 작업 관리 인터페이스
  • 사용자 정의 콘텐츠 정렬

주요 기능

  • 간단한 드래그 앤 드롭 재정렬
  • GridView와의 원활한 통합
  • 반응성 있고 부드러운 애니메이션
  • 필요한 설정 최소화
  • 사용자 정의 항목 위젯을 지원합니다

적합한 대상

  • 인터랙티브 UI를 구축하는 개발자
  • 사용자 중심의 콘텐츠 배치를 요구하는 앱
  • 동적 그리드 레이아웃을 가진 프로젝트
  • 드래그 앤 드롭 기능을 탐색하는 초보자
  • 정렬 가능한 그리드를 갖춘 UI 중심 애플리케이션

고려 사항

  • 수직 및 수평 그리드 레이아웃에 한정
  • 크로스 그리드 드래그에 대한 내장 지원 없음
  • 데이터 업데이트를 수동으로 처리해야 합니다
  • 매우 큰 데이터 세트에 최적화되지 않음
  • 사용자 정의 시각 효과를 위해 추가 스타일링이 필요할 수 있습니다

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

drag_and_drop_gridview

pub package Awesome Flutter Buy Me A Coffee

Drag And Drop GridView extends the functionality of the GridView widget in Flutter and gives you the freedom of creating a reorder the GridViewItems simple by Drag And Drop. It is super easy to implement and beautiful to use.

If you appreciate the content 📖, support projects visibility, give 👍| ⭐| 👏

Usage

To use this package, add drag_and_drop_gridview as a dependency in your pubspec.yaml file.

dependencies:
  drag_and_drop_gridview: ^1.0.8

And import the package in your code.

import 'package:drag_and_drop_gridview/devdrag.dart';

Examples

DragAndDropGridView ReorderableDragAndDropGridView ReorderableDragAndDropGridView ReorderableDragAndDropGridViewHover DragAndDropGridView ReorderableDragAndDropGridViewHover

Overview

DragAndDropGridView has the all same parameters (except shrinkWrap and scrollDirection) that GridView.builder constructor has.

But in DragAndDropGridView there are some required params gridDelegate, itemBuilder, onWillAccept, and onReorder.

gridDelegate

This is the same as we find it in the official gridview of Flutter. Learn More

gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        childAspectRatio: 3 / 4.5,
     ),
itemBuilder

This is the same as we find it in the official gridview of Flutter. Learn More

itemBuilder: (context, index) => Card(
       elevation: 2,
       child: Text(_animals[index]),
),
onWillAccept

This funciton allows you to validate if you want to accept the change in the order of the gridViewItems. If you always want to accept the change simply return true

// _animals = ['cat','dog','kitten','puppy']

onWillAccept: (oldIndex, newIndex) {
// Implement you own logic

// Example reject the reorder if the moving item's value is "kitten" 
if (_animals[newIndex] == "cat"){
	return false;
}
return true, // If you want to accept the child return true or else return false
},
onReorder

This function deals with changing the index of the newly arranged gridItems.

onReorder: (oldIndex, newIndex) {
	    _temp = _animals[newIndex];
        _animals[newIndex] = _animals[oldIndex];
        _animals[oldIndex] = _temp;
        setState(() {});
},
Example
 _animals = ['cat','dog','kitten','puppy']
 
DragAndDropGridView(
    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        childAspectRatio: 3 / 4.5,
    ),
    padding: EdgeInsets.all(20),
    itemBuilder: (context, index) => Card(
        elevation: 2,
        child: Text(_animals[index]),
		),
    ),
    itemCount: _animals.length,
    onWillAccept: (oldIndex, newIndex) {
		// Implement you own logic

		// Example reject the reorder if the moving item's destination value is cat"
		if (_animals[newIndex] == "cat"){
			return false;
		}
		return true, // If you want to accept the child return true or else return false
	},
    onReorder: (oldIndex, newIndex) {
	    _temp = _animals[newIndex];
        _animals[newIndex] = _animals[oldIndex];
        _animals[oldIndex] = _temp;
        setState(() {});
    },
)

Examples #1 : DragAndDropGridView

Below example shows you how to implement DragAndDropGridView easily.

import 'package:drag_and_drop_gridview/devdrag.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';

import 'package:flutter/services.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<String> _imageUris = [
    "https://images.pexels.com/photos/4466054/pexels-photo-4466054.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
    "https://images.pexels.com/photos/4561739/pexels-photo-4561739.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4507967/pexels-photo-4507967.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4321194/pexels-photo-4321194.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1053924/pexels-photo-1053924.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1624438/pexels-photo-1624438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/1144687/pexels-photo-1144687.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/2589010/pexels-photo-2589010.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
  ];

  int variableSet = 0;
  ScrollController _scrollController;
  double width;
  double height;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Drag And drop Plugin'),
        ),
        body: Center(
          child: DragAndDropGridView(
            controller: _scrollController,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              childAspectRatio: 3 / 4.5,
            ),
            padding: EdgeInsets.all(20),
            itemBuilder: (context, index) => Card(
              elevation: 2,
              child: LayoutBuilder(
                builder: (context, costrains) {
                  if (variableSet == 0) {
                    height = costrains.maxHeight;
                    width = costrains.maxWidth;
                    variableSet++;
                  }
                  return GridTile(
                    child: Image.network(
                      _imageUris[index],
                      fit: BoxFit.cover,
                      height: height,
                      width: width,
                    ),
                  );
                },
              ),
            ),
            itemCount: _imageUris.length,
            onWillAccept: (oldIndex, newIndex) {
              // Implement you own logic

              // Example reject the reorder if the moving item's value is something specific
              if (_imageUris[newIndex] == "something") {
                return false;
              }
              return true; // If you want to accept the child return true or else return false
            },
            onReorder: (oldIndex, newIndex) {
              final temp = _imageUris[oldIndex];
              _imageUris[oldIndex] = _imageUris[newIndex];
              _imageUris[newIndex] = temp;

              setState(() {});
            },
          ),
        ),
      ),
    );
  }
}


Result:
DragAndDropGridView
Example #2 : DragAndDropGridView Horizontal (Reorderable)

This is the example of how you can achive the Horizontal Reorderable / Re-Indexing feature in DragAndDropGridView. Just use horizontal constructor.

import 'package:drag_and_drop_gridview/devdrag.dart';
import 'package:drag_and_drop_gridview/drag.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';

import 'package:flutter/services.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<String> _imageUris = [
    "https://images.pexels.com/photos/4466054/pexels-photo-4466054.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
    "https://images.pexels.com/photos/4561739/pexels-photo-4561739.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4507967/pexels-photo-4507967.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4321194/pexels-photo-4321194.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1053924/pexels-photo-1053924.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1624438/pexels-photo-1624438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/1144687/pexels-photo-1144687.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/2589010/pexels-photo-2589010.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
  ];

  int variableSet = 0, variableSetHeader = 0;
  ScrollController _scrollController;
  double width;
  double height;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Horizontal DragAndDropGridView'),
        ),
        body: Center(
          child: DragAndDropGridView.horizontal(
            controller: _scrollController,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 5,
              childAspectRatio: 3 / 4.5,
            ),
            padding: EdgeInsets.all(20),
            itemBuilder: (context, index) => Card(
              elevation: 2,
              child: LayoutBuilder(builder: (context, costrains) {
                if (variableSet == 0) {
                  height = costrains.maxHeight;
                  width = costrains.maxWidth;
                  variableSet++;
                }
                return GridTile(
                  key: index == 4 ? Key("12") : null,
                  child: Image.network(
                    _imageUris[index],
                    fit: BoxFit.cover,
                    height: height,
                    width: width,
                  ),
                );
              }),
            ),
            itemCount: _imageUris.length,
            onWillAccept: (oldIndex, newIndex) => true,
            onReorder: (oldIndex, newIndex) {
              int indexOfFirstItem = _imageUris.indexOf(_imageUris[oldIndex]);
              int indexOfSecondItem = _imageUris.indexOf(_imageUris[newIndex]);

              if (indexOfFirstItem > indexOfSecondItem) {
                for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                    i > _imageUris.indexOf(_imageUris[newIndex]);
                    i--) {
                  var tmp = _imageUris[i - 1];
                  _imageUris[i - 1] = _imageUris[i];
                  _imageUris[i] = tmp;
                }
              } else {
                for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                    i < _imageUris.indexOf(_imageUris[newIndex]);
                    i++) {
                  var tmp = _imageUris[i + 1];
                  _imageUris[i + 1] = _imageUris[i];
                  _imageUris[i] = tmp;
                }
              }
              setState(() {});
            },
          ),
        ),
      ),
    );
  }
}

Result:
DragAndDropGridView ---
Example #3 : DragAndDropGridView Vertical (Reorderable)

This is the example of how you can achive the Vertical Reorderable / Re-Indexing feature in DragAndDropGridView.

import 'package:drag_and_drop_gridview/devdrag.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';

import 'package:flutter/services.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<String> _imageUris = [
    "https://images.pexels.com/photos/4466054/pexels-photo-4466054.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
    "https://images.pexels.com/photos/4561739/pexels-photo-4561739.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4507967/pexels-photo-4507967.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4321194/pexels-photo-4321194.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1053924/pexels-photo-1053924.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1624438/pexels-photo-1624438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/1144687/pexels-photo-1144687.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/2589010/pexels-photo-2589010.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
  ];

  int variableSet = 0;
  ScrollController _scrollController;
  double width;
  double height;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Vertical Drag And drop Plugin'),
        ),
        body: Center(
          child: DragAndDropGridView(
            controller: _scrollController,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              childAspectRatio: 3 / 4.5,
            ),
            padding: EdgeInsets.all(20),
            itemBuilder: (context, index) => Card(
              elevation: 2,
              child: LayoutBuilder(builder: (context, costrains) {
                if (variableSet == 0) {
                  height = costrains.maxHeight;
                  width = costrains.maxWidth;
                  variableSet++;
                }
                return GridTile(
                  child: Image.network(
                    _imageUris[index],
                    fit: BoxFit.cover,
                    height: height,
                    width: width,
                  ),
                );
              }),
            ),
            itemCount: _imageUris.length,
            onWillAccept: (oldIndex, newIndex) => true,
            onReorder: (oldIndex, newIndex) {
            
              // You can also implement on your own logic on reorderable
              
              int indexOfFirstItem = _imageUris.indexOf(_imageUris[oldIndex]);
              int indexOfSecondItem = _imageUris.indexOf(_imageUris[newIndex]);

              if (indexOfFirstItem > indexOfSecondItem) {
                for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                    i > _imageUris.indexOf(_imageUris[newIndex]);
                    i--) {
                  var tmp = _imageUris[i - 1];
                  _imageUris[i - 1] = _imageUris[i];
                  _imageUris[i] = tmp;
                }
              } else {
                for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                    i < _imageUris.indexOf(_imageUris[newIndex]);
                    i++) {
                  var tmp = _imageUris[i + 1];
                  _imageUris[i + 1] = _imageUris[i];
                  _imageUris[i] = tmp;
                }
              }
              setState(() {});
            },
          ),
        ),
      ),
    );
  }
}

Result
ReorderableDragAndDropGridView
Example #4: DragAndDropGridView with hover effect (Reorderable)

This is the example of how you can achive the Reordering Effect While Hovering Over A Specific Index feature in DragAndDropGridView.


import 'package:drag_and_drop_gridview/devdrag.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';
 
import 'package:flutter/services.dart';
 
void main() {
 runApp(MyApp());
}
 
class MyApp extends StatefulWidget {
 @override
 _MyAppState createState() => _MyAppState();
}
 
class _MyAppState extends State<MyApp> {
 List<String> _imageUris = [
   "https://images.pexels.com/photos/4466054/pexels-photo-4466054.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
   "https://images.pexels.com/photos/4561739/pexels-photo-4561739.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/4507967/pexels-photo-4507967.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/4321194/pexels-photo-4321194.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/1053924/pexels-photo-1053924.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/1624438/pexels-photo-1624438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
   "https://images.pexels.com/photos/1144687/pexels-photo-1144687.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
   "https://images.pexels.com/photos/2589010/pexels-photo-2589010.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
 ];
 
 int pos;
 
 List<String> tmpList;
 int variableSet = 0;
 ScrollController _scrollController;
 double width;
 double height;
 
 @override
 void initState() {
   tmpList = [..._imageUris];
   super.initState();
 }
 
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       appBar: AppBar(
         title: const Text('Vertical DragAndDropGridView Hover Effect'),
       ),
       body: Center(
         child: DragAndDropGridView(
           controller: _scrollController,
           gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
             crossAxisCount: 2,
             childAspectRatio: 3 / 4.5,
           ),
           padding: EdgeInsets.all(20),
           itemBuilder: (context, index) => Opacity(
             opacity: pos != null ? pos == index ? 0.6 : 1 : 1,
             child: Card(
               elevation: 2,
               child: LayoutBuilder(builder: (context, costrains) {
                 if (variableSet == 0) {
                   height = costrains.maxHeight;
                   width = costrains.maxWidth;
                   variableSet++;
                 }
                 return GridTile(
                   child: Image.network(
                     _imageUris[index],
                     fit: BoxFit.cover,
                     height: height,
                     width: width,
                   ),
                 );
               }),
             ),
           ),
           itemCount: _imageUris.length,
           onWillAccept: (oldIndex, newIndex) {
             _imageUris = [...tmpList];
             int indexOfFirstItem = _imageUris.indexOf(_imageUris[oldIndex]);
             int indexOfSecondItem = _imageUris.indexOf(_imageUris[newIndex]);
 
             if (indexOfFirstItem > indexOfSecondItem) {
               for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                   i > _imageUris.indexOf(_imageUris[newIndex]);
                   i--) {
                 var tmp = _imageUris[i - 1];
                 _imageUris[i - 1] = _imageUris[i];
                 _imageUris[i] = tmp;
               }
             } else {
               for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                   i < _imageUris.indexOf(_imageUris[newIndex]);
                   i++) {
                 var tmp = _imageUris[i + 1];
                 _imageUris[i + 1] = _imageUris[i];
                 _imageUris[i] = tmp;
               }
             }
 
             setState(
               () {
                 pos = newIndex;
               },
             );
             return true;
           },
           onReorder: (oldIndex, newIndex) {
             _imageUris = [...tmpList];
             int indexOfFirstItem = _imageUris.indexOf(_imageUris[oldIndex]);
             int indexOfSecondItem = _imageUris.indexOf(_imageUris[newIndex]);
 
             if (indexOfFirstItem > indexOfSecondItem) {
               for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                   i > _imageUris.indexOf(_imageUris[newIndex]);
                   i--) {
                 var tmp = _imageUris[i - 1];
                 _imageUris[i - 1] = _imageUris[i];
                 _imageUris[i] = tmp;
               }
             } else {
               for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                   i < _imageUris.indexOf(_imageUris[newIndex]);
                   i++) {
                 var tmp = _imageUris[i + 1];
                 _imageUris[i + 1] = _imageUris[i];
                 _imageUris[i] = tmp;
               }
             }
             tmpList = [..._imageUris];
             setState(
               () {
                 pos = null;
               },
             );
           },
         ),
       ),
     ),
   );
 }
}


Result
ReorderableDragAndDropGridViewHover
Example #5: DragAndDropGridView Non Sticky Header

In this example you can add a non sticky header.

But if you pass any vertical scrollview don't forgot to add shrinkwrap or wrap the widget in expanded to avoid error.

import 'package:drag_and_drop_gridview/devdrag.dart';
import 'package:drag_and_drop_gridview/drag.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';

import 'package:flutter/services.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<String> _imageUris = [
    "https://images.pexels.com/photos/4466054/pexels-photo-4466054.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
    "https://images.pexels.com/photos/4561739/pexels-photo-4561739.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4507967/pexels-photo-4507967.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4321194/pexels-photo-4321194.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1053924/pexels-photo-1053924.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1624438/pexels-photo-1624438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/1144687/pexels-photo-1144687.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/2589010/pexels-photo-2589010.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
  ];

  int variableSet = 0, variableSetHeader = 0;
  ScrollController _scrollController;
  double width;
  double height;
  double widthHeader;
  double heightHeader;
  List<String> listOfHeader = ["1", "2"];

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('DragAndDropGridView'),
        ),
        body: Center(
          child: DragAndDropGridView(
            header: Container(
              height: 50,
              width: double.infinity,
              alignment: Alignment.center,
              color: Colors.amber,
              child: Text(
                "Header",
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                ),
                textAlign: TextAlign.center,
              ),
            ),
            controller: _scrollController,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              childAspectRatio: 3 / 4.5,
            ),
            padding: EdgeInsets.all(20),
            itemBuilder: (context, index) => Card(
                elevation: 2,
                child: LayoutBuilder(builder: (context, costrains) {
                  if (variableSet == 0) {
                    height = costrains.maxHeight;
                    width = costrains.maxWidth;
                    variableSet++;
                  }
                  return GridTile(
                    key: index == 4 ? Key("12") : null,
                    child: Image.network(
                      _imageUris[index],
                      fit: BoxFit.cover,
                      height: height,
                      width: width,
                    ),
                  );
                }),
              ),
            itemCount: _imageUris.length,
            onWillAccept: (oldIndex, newIndex) => true,
            onReorder: (oldIndex, newIndex) {
              final temp = _imageUris[oldIndex];
              _imageUris[oldIndex] = _imageUris[newIndex];
              _imageUris[newIndex] = temp;
              setState(() {});
            },
          ),
        ),
      ),
    );
  }
}

Result
ReorderableDragAndDropGridViewHover
Example #6: DragAndDrop GridView with non-draggable child

In the itembuilder just wrap your widget in DragItem and return isDraggable true or false acording to your condition.

And in isDropable if you pass false then this item will not accept any draggable child. By default it is set to true true.


import 'package:drag_and_drop_gridview/drag.dart'; // import this header

DragItem(
    isDraggable: true, // whether draggable or not (Default true)
    isDropable: false, // whether dropable or not (Default true)
    child: ..///, //and pass the child
);

Example#7: Sticky header horizontal gridview

To achive the sticky header in gridview just call this horizontalStickyHeader constructor. By Default allHeaderChildNonDraggable is set to false making all header draggable.

onWillAcceptHeader (Implement your logic on accepting and rejecting the drop of an header element),

onReorderHeader (implement your logic for reodering and reindexing the elements)

And if you want the header to be non-draggable element simple set allHeaderChildNonDraggable to true.

and required parameters are: onWillAccept, itemBuilderHeader, onReorder, gridDelegate, itemBuilder


import 'package:drag_and_drop_gridview/devdrag.dart';
import 'package:drag_and_drop_gridview/drag.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';

import 'package:flutter/services.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<String> _imageUris = [
    "https://images.pexels.com/photos/4466054/pexels-photo-4466054.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
    "https://images.pexels.com/photos/4561739/pexels-photo-4561739.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4507967/pexels-photo-4507967.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4321194/pexels-photo-4321194.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1053924/pexels-photo-1053924.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1624438/pexels-photo-1624438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/1144687/pexels-photo-1144687.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/2589010/pexels-photo-2589010.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",


    "https://images.pexels.com/photos/443446/pexels-photo-443446.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/2113566/pexels-photo-2113566.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/3244513/pexels-photo-3244513.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1438761/pexels-photo-1438761.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/2835562/pexels-photo-2835562.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/2440021/pexels-photo-2440021.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/572897/pexels-photo-572897.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
  ];

  int variableSet = 0, variableSetHeader = 0;
  ScrollController _scrollController;
  double width;
  double height;
  double widthHeader;
  double heightHeader;
  List<String> listOfHeader = ["1", "2", "3", "4", "5"];

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('DragAndDropGridView'),
        ),
        body: Center(
          child: DragAndDropGridView.horizontalStickyHeader(
            itemBuilderHeader: (context, pos) => Card(
              elevation: 2,
              child: LayoutBuilder(builder: (context, costrains) {
                if (variableSet == 0) {
                  heightHeader = costrains.maxHeight;
                  widthHeader = costrains.maxWidth;
                  variableSetHeader++;
                }
                return Container(
                  height: heightHeader,
                  width: widthHeader,
                  alignment: Alignment.center,
                  child: Text(
                    "${listOfHeader[pos]}",
                    textAlign: TextAlign.center,
                  ),
                );
              }),
            ),
            headerItemCount: 5,
            headerPadding: EdgeInsets.all(10),
            headerGridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 5,
              childAspectRatio: 2.8,
            ),
            onReorderHeader: (oldIndex, newIndex) {
              var temp = listOfHeader[oldIndex];
              listOfHeader[oldIndex] = listOfHeader[newIndex];
              listOfHeader[newIndex] = temp;
              setState(() {});
            },
            onWillAcceptHeader: (oldIndex, newIndex) {
              return true;
            },
            controller: _scrollController,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 5,
              childAspectRatio: 3 / 4.5,
            ),
            padding: EdgeInsets.all(20),
            itemBuilder: (context, index) => DragItem(
              child: Card(
                elevation: 2,
                child: LayoutBuilder(builder: (context, costrains) {
                  if (variableSet == 0) {
                    height = costrains.maxHeight;
                    width = costrains.maxWidth;
                    variableSet++;
                  }
                  return GridTile(
                    key: index == 4 ? Key("12") : null,
                    child: Image.network(
                      _imageUris[index],
                      fit: BoxFit.cover,
                      height: height,
                      width: width,
                    ),
                  );
                }),
              ),
            ),
            itemCount: _imageUris.length,
            onWillAccept: (oldIndex, newIndex) => true,
            onReorder: (oldIndex, newIndex) {
              int indexOfFirstItem = _imageUris.indexOf(_imageUris[oldIndex]);
              int indexOfSecondItem = _imageUris.indexOf(_imageUris[newIndex]);

              if (indexOfFirstItem > indexOfSecondItem) {
                for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                    i > _imageUris.indexOf(_imageUris[newIndex]);
                    i--) {
                  var tmp = _imageUris[i - 1];
                  _imageUris[i - 1] = _imageUris[i];
                  _imageUris[i] = tmp;
                }
              } else {
                for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                    i < _imageUris.indexOf(_imageUris[newIndex]);
                    i++) {
                  var tmp = _imageUris[i + 1];
                  _imageUris[i + 1] = _imageUris[i];
                  _imageUris[i] = tmp;
                }
              }
              setState(() {});
            },
          ),
        ),
      ),
    );
  }
}

Result
ReorderableDragAndDropGridViewHover
Example#8: Sticky header virtical gridview

To achive the sticky header in gridview just call this stickyHeader constructor.

By Default allHeaderChildNonDraggable is set to false making all header draggable.

onWillAcceptHeader (Implement your logic on accepting and rejecting the drop of an header element),

onReorderHeader (implement your logic for reodering and reindexing the elements)

And if you want the header to be non-draggable element simple set allHeaderChildNonDraggable to true.

and required parameters are: onWillAccept, itemBuilderHeader, onReorder, gridDelegate, itemBuilder


import 'package:drag_and_drop_gridview/devdrag.dart';
import 'package:drag_and_drop_gridview/drag.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';

import 'package:flutter/services.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<String> _imageUris = [
    "https://images.pexels.com/photos/4466054/pexels-photo-4466054.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
    "https://images.pexels.com/photos/4561739/pexels-photo-4561739.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4507967/pexels-photo-4507967.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/4321194/pexels-photo-4321194.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1053924/pexels-photo-1053924.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "https://images.pexels.com/photos/1624438/pexels-photo-1624438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/1144687/pexels-photo-1144687.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
    "https://images.pexels.com/photos/2589010/pexels-photo-2589010.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
  ];

  int variableSet = 0, variableSetHeader = 0;
  ScrollController _scrollController;
  double width;
  double height;
  double widthHeader;
  double heightHeader;
  List<String> listOfHeader = ["1", "2"];

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('DragAndDropGridView'),
        ),
        body: Center(
          child: DragAndDropGridView.stickyHeader(
            itemBuilderHeader: (context, pos) => Card(
              elevation: 2,
              child: LayoutBuilder(builder: (context, costrains) {
                if (variableSet == 0) {
                  heightHeader = costrains.maxHeight;
                  widthHeader = costrains.maxWidth;
                  variableSetHeader++;
                }
                return Container(
                  height: heightHeader,
                  width: widthHeader,
                  alignment: Alignment.center,
                  child: Text(
                    "${listOfHeader[pos]}",
                    textAlign: TextAlign.center,
                  ),
                );
              }),
            ),
            headerItemCount: 2,
            headerPadding: EdgeInsets.all(10),
            headerGridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              childAspectRatio: 2.8,
            ),
            onReorderHeader: (oldIndex, newIndex) {
              var temp = listOfHeader[oldIndex];
              listOfHeader[oldIndex] = listOfHeader[newIndex];
              listOfHeader[newIndex] = temp;
              setState(() {});
            },
            onWillAcceptHeader: (oldIndex, newIndex) {
              return true;
            },
            controller: _scrollController,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              childAspectRatio: 3 / 4.5,
            ),
            padding: EdgeInsets.all(10),
            itemBuilder: (context, index) => Card(
              elevation: 2,
              child: LayoutBuilder(builder: (context, costrains) {
                if (variableSet == 0) {
                  height = costrains.maxHeight;
                  width = costrains.maxWidth;
                  variableSet++;
                }
                return GridTile(
                  key: index == 4 ? Key("12") : null,
                  child: Image.network(
                    _imageUris[index],
                    fit: BoxFit.cover,
                    height: height,
                    width: width,
                  ),
                );
              }),
            ),
            itemCount: _imageUris.length,
            onWillAccept: (oldIndex, newIndex) => true,
            onReorder: (oldIndex, newIndex) {
              int indexOfFirstItem = _imageUris.indexOf(_imageUris[oldIndex]);
              int indexOfSecondItem = _imageUris.indexOf(_imageUris[newIndex]);

              if (indexOfFirstItem > indexOfSecondItem) {
                for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                    i > _imageUris.indexOf(_imageUris[newIndex]);
                    i--) {
                  var tmp = _imageUris[i - 1];
                  _imageUris[i - 1] = _imageUris[i];
                  _imageUris[i] = tmp;
                }
              } else {
                for (int i = _imageUris.indexOf(_imageUris[oldIndex]);
                    i < _imageUris.indexOf(_imageUris[newIndex]);
                    i++) {
                  var tmp = _imageUris[i + 1];
                  _imageUris[i + 1] = _imageUris[i];
                  _imageUris[i] = tmp;
                }
              }
              setState(() {});
            },
          ),
        ),
      ),
    );
  }
}


Result
ReorderableDragAndDropGridViewHover
Example #9: DragAndDropGridView change child

You can change the child by set the isCustomChildWhenDragging to true and return your child to this parameter childWhenDragging.


import 'package:drag_and_drop_gridview/devdrag.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';
 
import 'package:flutter/services.dart';
 
void main() {
 runApp(MyApp());
}
 
class MyApp extends StatefulWidget {
 @override
 _MyAppState createState() => _MyAppState();
}
 
class _MyAppState extends State<MyApp> {
 List<String> _imageUris = [
   "https://images.pexels.com/photos/4466054/pexels-photo-4466054.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
   "https://images.pexels.com/photos/4561739/pexels-photo-4561739.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/4507967/pexels-photo-4507967.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/4321194/pexels-photo-4321194.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/1053924/pexels-photo-1053924.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/1624438/pexels-photo-1624438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
   "https://images.pexels.com/photos/1144687/pexels-photo-1144687.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
   "https://images.pexels.com/photos/2589010/pexels-photo-2589010.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
 ];
 
 int variableSet = 0;
 ScrollController _scrollController;
 double width;
 double height;
 
 @override
 void initState() {
   super.initState();
 }
 
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       appBar: AppBar(
         title: const Text('DragAndDropGridView'),
       ),
       body: Center(
         child: DragAndDropGridView(
           controller: _scrollController,
           gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
             crossAxisCount: 2,
             childAspectRatio: 3 / 4.5,
           ),
           padding: EdgeInsets.all(20),
           itemBuilder: (context, index) => Card(
             elevation: 2,
             child: LayoutBuilder(builder: (context, costrains) {
               if (variableSet == 0) {
                 height = costrains.maxHeight;
                 width = costrains.maxWidth;
                 variableSet++;
               }
               return GridTile(
                 child: Image.network(
                   _imageUris[index],
                   height: height,
                   width: width,
                 ),
               );
             }),
           ),
           isCustomChildWhenDragging: true,
           childWhenDragging: (pos) => Image.asset(
             "gifs/draganddropbg.jpg",
             height: height,
             width: width,
           ),
           itemCount: _imageUris.length,
           onWillAccept: (oldIndex, newIndex) => true,
           onReorder: (oldIndex, newIndex) {
             final temp = _imageUris[oldIndex];
             _imageUris[oldIndex] = _imageUris[newIndex];
             _imageUris[newIndex] = temp;
 
             setState(() {});
           },
         ),
       ),
     ),
   );
 }
}


Result
ReorderableDragAndDropGridViewChildChange
Example #10: DragAndDropGridView change feedback

You can change the child by set the isCustomFeedback to true and return your child to this parameter feedback.


import 'package:drag_and_drop_gridview/devdrag.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';
 
import 'package:flutter/services.dart';
 
void main() {
 runApp(MyApp());
}
 
class MyApp extends StatefulWidget {
 @override
 _MyAppState createState() => _MyAppState();
}
 
class _MyAppState extends State<MyApp> {
 List<String> _imageUris = [
   "https://images.pexels.com/photos/4466054/pexels-photo-4466054.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
   "https://images.pexels.com/photos/4561739/pexels-photo-4561739.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/4507967/pexels-photo-4507967.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/4321194/pexels-photo-4321194.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/1053924/pexels-photo-1053924.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
   "https://images.pexels.com/photos/1624438/pexels-photo-1624438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
   "https://images.pexels.com/photos/1144687/pexels-photo-1144687.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
   "https://images.pexels.com/photos/2589010/pexels-photo-2589010.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
 ];
 
 int variableSet = 0;
 ScrollController _scrollController;
 double width;
 double height;
 
 @override
 void initState() {
   super.initState();
 }
 
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       appBar: AppBar(
         title: const Text('DragAndDropGridView'),
       ),
       body: Center(
         child: DragAndDropGridView(
           controller: _scrollController,
           gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
             crossAxisCount: 2,
             childAspectRatio: 3 / 4.5,
           ),
           padding: EdgeInsets.all(20),
           itemBuilder: (context, index) => Card(
             elevation: 2,
             child: LayoutBuilder(builder: (context, costrains) {
               if (variableSet == 0) {
                 height = costrains.maxHeight;
                 width = costrains.maxWidth;
                 variableSet++;
               }
               return GridTile(
                 child: Image.network(
                   _imageUris[index],
                   height: height,
                   width: width,
                 ),
               );
             }),
           ),
           isCustomFeedback: true,
           feedback: (pos) => Image.asset(
             "gifs/draganddropbg.jpg",
             height: height,
             width: width,
           ),
           itemCount: _imageUris.length,
           onWillAccept: (oldIndex, newIndex) => true,
           onReorder: (oldIndex, newIndex) {
             final temp = _imageUris[oldIndex];
             _imageUris[oldIndex] = _imageUris[newIndex];
             _imageUris[newIndex] = temp;
 
             setState(() {});
           },
         ),
       ),
     ),
   );
 }
}


Result
ReorderableDragAndDropGridViewFeedbackChange

Support

You can also support us by buying coffee. Your support is very much appreciated. :)

Buy Me A Coffee

카테고리

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.