欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android?Flutter實現(xiàn)任意拖動的控件

 更新時間:2023年07月02日 09:57:48   作者:CodeOfCC  
使用flutter開發(fā)是需要控件能拖動,比如畫板中的元素,或者工具條等,所以本文為大家準備了Flutter實現(xiàn)任意拖動控件的示例代碼,希望對大家有所幫助

前言

使用flutter開發(fā)是需要控件能拖動,比如畫板中的元素,或者工具條,搜索框,每個都單獨去實現(xiàn)拖動還是比較麻煩的,將拖動功能封裝成一個控件,需要的時候直接使用拖動控件作為父控件這樣就方便很多了。

一、如何實現(xiàn)

1、使用GestureDetector響應拖動事件

//總位移
var _unlimtedOffset = Offset.zero;
//當前位移(有活動區(qū)域限制時,鼠標超過邊界后當前位移不等于總位移,此時總位移可以確?;氐竭吔鐑仁髽伺c控件的相對位置不變)
final _offset = ValueNotifier<Offset>(Offset.zero);
GestureDetector(
  child: this.widget.child,
   onPanUpdate: (detail) {
       //累加拖動距離
      _unlimtedOffset += detail.delta;
 }
)

2、使用Transform變換控件位置

使用translate變換位置即可

//ValueListenableBuilder監(jiān)聽_offset 改變,此處略
Transform.translate(
    offset: offset,
    child:GestureDetector()//上一步的child:GestureDetector
)

3、計算拖動區(qū)域

這一步不是必須的,但是如果需要限制控件活動范圍則需要這一步。

通過GlobalKey獲取控件大小,在GestureDetector的onPanUpdate事件中:

onPanUpdate: (detail) {
   //拖動區(qū)域為父控件,去掉則不受限制,但拖出父控件會被遮擋無法點擊。
   //獲取父控件大小
   RenderBox ? parentRenderBox = _mykey.currentContext
   ? .findAncestorRenderObjectOfType<RenderObject>() as RenderBox ? ;
   final screenSize = parentRenderBox ? .size;
   //獲取控件大小
   final mySize = _mykey.currentContext ? .size;
   final renderBox =
   _mykey.currentContext ? .findRenderObject() as RenderBox ? ;
   //獲取控件當前位置    
   var originOffset = renderBox ? .localToGlobal(Offset.zero);
   if (originOffset != null) {
   	originOffset = parentRenderBox ? .globalToLocal(originOffset);
   }
   if (screenSize == null || mySize == null || originOffset == null) {
   	return;
   }
   //計算不超出父控件區(qū)域
   if (off.dx < -originOffset.dx) {
   	off = Offset(-originOffset.dx, off.dy);
   }
   else if (off.dx >
   	screenSize.width - mySize.width - originOffset.dx) {
   	off = Offset(
   		screenSize.width - mySize.width - originOffset.dx,
   		off.dy,
   		);
   }
   if (off.dy < -originOffset.dy) {
   	off = Offset(off.dx, -originOffset.dy);
   }
   else if (off.dy >
   	screenSize.height - mySize.height - originOffset.dy) {
   	off = Offset(
   		off.dx,
   		screenSize.height - mySize.height - originOffset.dy,
   		);
   }
   //現(xiàn)在活動區(qū)域為父控件 --end
}

二、完整代碼

drag_move_box.dart

import 'package:flutter/material.dart';
/// 可拖動容器
/// 拖動范圍是父控件
class DragMoveBox extends StatefulWidget {
  final Widget child;
  const DragMoveBox({
    super.key,
    required this.child,
  });
  @override
  State<DragMoveBox> createState() => _DragMoveBoxState();
}
class _DragMoveBoxState extends State<DragMoveBox> {
  final GlobalKey _mykey = GlobalKey();
  //當前位移(有活動區(qū)域限制時,鼠標超過邊界后當前位移不等于總位移,此時總位移可以確?;氐竭吔鐑仁髽伺c控件的相對位置不變)
  final _offset = ValueNotifier<Offset>(Offset.zero);
  //總位移
  var _unlimtedOffset = Offset.zero;
  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder(
      valueListenable: _offset,
      builder:
          //采用transform變換實現(xiàn)拖動
          (context, offset, widget) => Transform.translate(
        key: _mykey,
        offset: offset,
        child: GestureDetector(
          child: this.widget.child,
          onPanUpdate: (detail) {
            var off = _unlimtedOffset = _unlimtedOffset + detail.delta;
            //拖動區(qū)域為父控件,去掉則不受限制,但拖出父控件會被遮擋無法點擊。
            //獲取父控件大小
            RenderBox? parentRenderBox = _mykey.currentContext
                ?.findAncestorRenderObjectOfType<RenderObject>() as RenderBox?;
            final screenSize = parentRenderBox?.size;
            //獲取控件大小
            final mySize = _mykey.currentContext?.size;
            final renderBox =
                _mykey.currentContext?.findRenderObject() as RenderBox?;
            //獲取控件當前位置    
            var originOffset = renderBox?.localToGlobal(Offset.zero);
            if (originOffset != null) {
              originOffset = parentRenderBox?.globalToLocal(originOffset);
            }
            if (screenSize == null || mySize == null || originOffset == null) {
              return;
            }
            //計算不超出父控件區(qū)域
            if (off.dx < -originOffset.dx) {
              off = Offset(-originOffset.dx, off.dy);
            } else if (off.dx >
                screenSize.width - mySize.width - originOffset.dx) {
              off = Offset(
                screenSize.width - mySize.width - originOffset.dx,
                off.dy,
              );
            }
            if (off.dy < -originOffset.dy) {
              off = Offset(off.dx, -originOffset.dy);
            } else if (off.dy >
                screenSize.height - mySize.height - originOffset.dy) {
              off = Offset(
                off.dx,
                screenSize.height - mySize.height - originOffset.dy,
              );
            }
            //現(xiàn)在活動區(qū)域為父控件 --end
            _offset.value = off;
          },
        ),
      ),
    );
  }
}

三、使用示例

1、基本用法

DragMoveBox(
child:Text("You have pushed the button this many times:") //需要拖動的控件
)

2.效果預覽

總結

本文提供了一種簡單的拖動控件實現(xiàn),尤其是封裝成容器后使用變得很簡單,主要在于能想到translate變換可以改變位置,在了解通過GlobalKey獲取控件大小以及獲取控件大小的方法,很容易就實現(xiàn)拖動功能了。

以上就是Android Flutter實現(xiàn)任意拖動的控件的詳細內容,更多關于Android Flutter任意拖動控件的資料請關注腳本之家其它相關文章!

相關文章

  • Android自定義桌面功能代碼實現(xiàn)

    Android自定義桌面功能代碼實現(xiàn)

    android自定義桌面其實很簡單,看一個例子就明白了
    2013-11-11
  • Android Studio 代理配置指南(小結)

    Android Studio 代理配置指南(小結)

    這篇文章主要介紹了Android Studio 代理配置指南(小結),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • Kotlin擴展函數(shù)與運算符重載超詳細解析

    Kotlin擴展函數(shù)與運算符重載超詳細解析

    Kotlin可以為一個不能修改的或來自第三方庫中的類編寫一個新的函數(shù)。這個新增的函數(shù)就像那個原始類本來就有的函數(shù)一樣,可以用普通的方法調用,這種機制的函數(shù)稱為擴展函數(shù)
    2022-11-11
  • Android 單雙擊實現(xiàn)的方法步驟

    Android 單雙擊實現(xiàn)的方法步驟

    這篇文章主要介紹了Android 單雙擊實現(xiàn)的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • Android設置theme中可能遇到的坑

    Android設置theme中可能遇到的坑

    Theme是一套UI控件和Activity的樣式,下面這篇文章主要給大家介紹了關于Android設置theme中可能遇到的坑的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧
    2018-06-06
  • Android 數(shù)據(jù)存儲方式有哪幾種

    Android 數(shù)據(jù)存儲方式有哪幾種

    android為數(shù)據(jù)存儲提供了五種方式,有SharedPreferences、文件存儲、SQLite數(shù)據(jù)庫、ContentProvider、網(wǎng)絡存儲,對android數(shù)據(jù)存儲方式感興趣的朋友可以通過本文學習一下
    2015-11-11
  • Android布局技巧之include、merge與ViewStub標簽的巧用

    Android布局技巧之include、merge與ViewStub標簽的巧用

    Android 官方提供了三個用來優(yōu)化布局的標簽,分別是include、merge與ViewStub,下面這篇文章主要給大家介紹了關于Android布局技巧之include、merge與ViewStub標簽巧用的相關資料,需要的朋友可以參考下
    2018-06-06
  • android 之Spinner下拉菜單實現(xiàn)級聯(lián)

    android 之Spinner下拉菜單實現(xiàn)級聯(lián)

    android 之Spinner下拉菜單實現(xiàn)級聯(lián),需要的朋友可以參考一下
    2013-02-02
  • Android App實現(xiàn)監(jiān)聽軟鍵盤按鍵的三種方式

    Android App實現(xiàn)監(jiān)聽軟鍵盤按鍵的三種方式

    本篇文章主要介紹Android App實現(xiàn)監(jiān)聽軟鍵盤按鍵的三種方式,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • 代碼分析Android實現(xiàn)側滑菜單

    代碼分析Android實現(xiàn)側滑菜單

    現(xiàn)在app越來越注重用戶體驗,本文給大家分析android實現(xiàn)側滑菜單的代碼,代碼簡單易懂,感興趣的朋友一起看看吧
    2015-11-11

最新評論