国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Flutter 實(shí)現(xiàn)任意控件拖動(dòng)

這篇具有很好參考價(jià)值的文章主要介紹了Flutter 實(shí)現(xiàn)任意控件拖動(dòng)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。


前言

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


一、如何實(shí)現(xiàn)?

1、使用GestureDetector響應(yīng)拖動(dòng)事件

//總位移
var _unlimtedOffset = Offset.zero;
//當(dāng)前位移(有活動(dòng)區(qū)域限制時(shí),鼠標(biāo)超過(guò)邊界后當(dāng)前位移不等于總位移,此時(shí)總位移可以確?;氐竭吔鐑?nèi)鼠標(biāo)與控件的相對(duì)位置不變)
final _offset = ValueNotifier<Offset>(Offset.zero);
GestureDetector(
  child: this.widget.child,
   onPanUpdate: (detail) {
       //累加拖動(dòng)距離
      _unlimtedOffset += detail.delta;
 }
)

2、使用Transform變換控件位置

使用translate變換位置即可

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

3、計(jì)算拖動(dòng)區(qū)域

這一步不是必須的,但是如果需要限制控件活動(dòng)范圍則需要這一步。
通過(guò)GlobalKey獲取控件大小,在GestureDetector的onPanUpdate事件中:

onPanUpdate: (detail) {
   //拖動(dòng)區(qū)域?yàn)楦缚丶?,去掉則不受限制,但拖出父控件會(huì)被遮擋無(wú)法點(diǎn)擊。
   //獲取父控件大小
   RenderBox ? parentRenderBox = _mykey.currentContext
   ? .findAncestorRenderObjectOfType<RenderObject>() as RenderBox ? ;
   final screenSize = parentRenderBox ? .size;
   //獲取控件大小
   final mySize = _mykey.currentContext ? .size;
   final renderBox =
   _mykey.currentContext ? .findRenderObject() as RenderBox ? ;
   //獲取控件當(dāng)前位置    
   var originOffset = renderBox ? .localToGlobal(Offset.zero);
   if (originOffset != null) {
   	originOffset = parentRenderBox ? .globalToLocal(originOffset);
   }
   if (screenSize == null || mySize == null || originOffset == null) {
   	return;
   }
   //計(jì)算不超出父控件區(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)在活動(dòng)區(qū)域?yàn)楦缚丶?--end
}

二、完整代碼

drag_move_box.dart

import 'package:flutter/material.dart';

/// 可拖動(dòng)容器
/// 拖動(dòng)范圍是父控件
class DragMoveBox extends StatefulWidget {
  final Widget child;
  const DragMoveBox({
    super.key,
    required this.child,
  });
  
  State<DragMoveBox> createState() => _DragMoveBoxState();
}

class _DragMoveBoxState extends State<DragMoveBox> {
  final GlobalKey _mykey = GlobalKey();
  //當(dāng)前位移(有活動(dòng)區(qū)域限制時(shí),鼠標(biāo)超過(guò)邊界后當(dāng)前位移不等于總位移,此時(shí)總位移可以確?;氐竭吔鐑?nèi)鼠標(biāo)與控件的相對(duì)位置不變)
  final _offset = ValueNotifier<Offset>(Offset.zero);
  //總位移
  var _unlimtedOffset = Offset.zero;
  
  Widget build(BuildContext context) {
    return ValueListenableBuilder(
      valueListenable: _offset,
      builder:
          //采用transform變換實(shí)現(xiàn)拖動(dòng)
          (context, offset, widget) => Transform.translate(
        key: _mykey,
        offset: offset,
        child: GestureDetector(
          child: this.widget.child,
          onPanUpdate: (detail) {
            var off = _unlimtedOffset = _unlimtedOffset + detail.delta;
            //拖動(dòng)區(qū)域?yàn)楦缚丶?,去掉則不受限制,但拖出父控件會(huì)被遮擋無(wú)法點(diǎn)擊。
            //獲取父控件大小
            RenderBox? parentRenderBox = _mykey.currentContext
                ?.findAncestorRenderObjectOfType<RenderObject>() as RenderBox?;
            final screenSize = parentRenderBox?.size;
            //獲取控件大小
            final mySize = _mykey.currentContext?.size;
            final renderBox =
                _mykey.currentContext?.findRenderObject() as RenderBox?;
            //獲取控件當(dāng)前位置    
            var originOffset = renderBox?.localToGlobal(Offset.zero);
            if (originOffset != null) {
              originOffset = parentRenderBox?.globalToLocal(originOffset);
            }
            if (screenSize == null || mySize == null || originOffset == null) {
              return;
            }
            //計(jì)算不超出父控件區(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)在活動(dòng)區(qū)域?yàn)楦缚丶?--end
            _offset.value = off;
          },
        ),
      ),
    );
  }
}

三、使用示例

1、基本用法

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

效果預(yù)覽
flutter 移動(dòng)組件,flutter,flutter,前端,dart,windows,android


總結(jié)

以上就是今天要講的內(nèi)容,本文提供了一種簡(jiǎn)單的拖動(dòng)控件實(shí)現(xiàn),尤其是封裝成容器后使用變得很簡(jiǎn)單,主要在于能想到translate變換可以改變位置,在了解通過(guò)GlobalKey獲取控件大小以及獲取控件大小的方法,很容易就實(shí)現(xiàn)拖動(dòng)功能了。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-613025.html

到了這里,關(guān)于Flutter 實(shí)現(xiàn)任意控件拖動(dòng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Flutter】Flutter Text 控件實(shí)現(xiàn)下劃線、刪除線、虛線、加粗、斜體

    在 Flutter 開發(fā)中,我們經(jīng)常需要對(duì) Text 控件進(jìn)行各種樣式的設(shè)置,包括但不限于下劃線、刪除線、虛線、加粗和斜體等。這些樣式的設(shè)置可以幫助我們更好地展示文本內(nèi)容,提升用戶體驗(yàn)。本文將詳細(xì)介紹如何在 Flutter 3.10.0 或更高版本中實(shí)現(xiàn)這些效果。閱讀本文后,你將掌握

    2024年02月06日
    瀏覽(18)
  • Flutter實(shí)現(xiàn)Android拖動(dòng)到垃圾桶刪除效果-Draggable和DragTarget的詳細(xì)講解

    Flutter實(shí)現(xiàn)Android拖動(dòng)到垃圾桶刪除效果-Draggable和DragTarget的詳細(xì)講解

    Draggable是Flutter框架中的一個(gè)小部件,用于支持用戶通過(guò)手勢(shì)拖動(dòng)一個(gè)子部件。它是基于手勢(shì)的一種方式,可以使用戶可以在屏幕上拖動(dòng)指定的部件。以下是關(guān)于Draggable的一些詳細(xì)介紹: Draggable的構(gòu)造函數(shù) child (Widget): 被拖動(dòng)的子部件。 feedback (Widget?): 拖動(dòng)時(shí)顯示的反饋部件。

    2024年02月04日
    瀏覽(20)
  • 給前端開發(fā)的一份 flutter 常用組件指南

    可以理解為 div 元素,可設(shè)置寬高等屬性 常用屬性如下: 屬性 類型 描述 width double 寬 height double 高 padding EdgeInsetsGeometry 內(nèi)邊距 margin EdgeInsetsGeometry 外邊距 color Color 背景色,注意不能跟 decoration.color 同時(shí)使用,會(huì)報(bào)錯(cuò) decoration Decoration 盒模型裝飾器 示例: 等價(jià)于以下的樣式

    2024年02月11日
    瀏覽(44)
  • Flutter 實(shí)現(xiàn)按位置大小比例布局的控件

    Flutter 實(shí)現(xiàn)按位置大小比例布局的控件

    做視頻監(jiān)控項(xiàng)目時(shí)需要需要展示多分屏,比如2x2、3x3、414等等,如果每一種分屏都單獨(dú)實(shí)現(xiàn)會(huì)很麻煩,而且不能支持用戶定制。最好的方式還是實(shí)現(xiàn)一個(gè)通用的分屏容器,而且采樣比例計(jì)算位置大小,可以適配任意尺寸。 最直觀的實(shí)現(xiàn)方式是獲取控件寬高然后按比例計(jì)算,但

    2024年02月13日
    瀏覽(16)
  • Android應(yīng)用-Flutter實(shí)現(xiàn)Android拖動(dòng)到垃圾桶刪除效果-Draggable和DragTarget的詳細(xì)講解

    Android應(yīng)用-Flutter實(shí)現(xiàn)Android拖動(dòng)到垃圾桶刪除效果-Draggable和DragTarget的詳細(xì)講解

    Draggable是Flutter框架中的一個(gè)小部件,用于支持用戶通過(guò)手勢(shì)拖動(dòng)一個(gè)子部件。它是基于手勢(shì)的一種方式,可以使用戶可以在屏幕上拖動(dòng)指定的部件。以下是關(guān)于Draggable的一些詳細(xì)介紹: Draggable的構(gòu)造函數(shù) child (Widget): 被拖動(dòng)的子部件。 feedback (Widget?): 拖動(dòng)時(shí)顯示的反饋部件。

    2024年02月04日
    瀏覽(14)
  • Flutter一天一控件之ListTile(列表的實(shí)現(xiàn))

    Flutter一天一控件之ListTile(列表的實(shí)現(xiàn))

    Flutter中的ListTile控件是一種常用的列表項(xiàng)控件,它可以用于顯示列表中的每一個(gè)項(xiàng),通常包含標(biāo)題、副標(biāo)題、圖標(biāo)等內(nèi)容。ListTile控件的外觀和行為類似于Android中的ListView中的列表項(xiàng)。 上面的代碼中,我們創(chuàng)建了一個(gè)ListTile控件,包含一個(gè)左側(cè)圖標(biāo)、一個(gè)標(biāo)題、一個(gè)副標(biāo)題和

    2024年02月05日
    瀏覽(17)
  • Flutter 用Texture控件在Windows平臺(tái)實(shí)現(xiàn)視頻渲染

    提示:閱讀此文章之前需要有C++開發(fā)經(jīng)驗(yàn),知道如何利用channel在C++和Dart之間做通信。 前言 一、PlatformView與Texture是什么? 二、使用步驟 1.在Flutter需要顯示視頻的地方聲明Texture組件 2.在Windows插件代碼里面創(chuàng)建TextureRenderer類 3.Flutter通過(guò)channel調(diào)用Windows插件創(chuàng)建Texture 4.Windows插

    2023年04月12日
    瀏覽(19)
  • Flutter的AspectRatio控件實(shí)現(xiàn)視頻播放、圖片播放按照長(zhǎng)寬比縮放

    AspectRatio小部件用于調(diào)整其子級(jí)小部件的寬高比。它將其子級(jí)小部件的寬度調(diào)整為給定的寬度,并根據(jù)寬度計(jì)算出相應(yīng)的高度,以保持指定的寬高比。 調(diào)整容器的寬高比: 當(dāng)您希望在布局中使用容器或小部件時(shí),以特定的寬高比顯示內(nèi)容時(shí),可以使用AspectRatio。 例如,您可能

    2024年02月13日
    瀏覽(18)
  • flutter開發(fā)實(shí)戰(zhàn)-實(shí)現(xiàn)左右來(lái)回移動(dòng)的按鈕引導(dǎo)動(dòng)畫效果

    flutter開發(fā)實(shí)戰(zhàn)-實(shí)現(xiàn)左右來(lái)回移動(dòng)的按鈕引導(dǎo)動(dòng)畫效果

    flutter開發(fā)實(shí)戰(zhàn)-實(shí)現(xiàn)左右來(lái)回移動(dòng)的按鈕引導(dǎo)動(dòng)畫效果 最近開發(fā)過(guò)程中需要實(shí)現(xiàn)左右來(lái)回移動(dòng)的按鈕引導(dǎo)動(dòng)畫效果 AnimationController用來(lái)控制一個(gè)或者多個(gè)動(dòng)畫的正向、反向、停止等相關(guān)動(dòng)畫操作。在默認(rèn)情況下AnimationController是按照線性進(jìn)行動(dòng)畫播放的。AnimationController兩個(gè)監(jiān)聽

    2024年02月13日
    瀏覽(95)
  • Qt獲取鼠標(biāo)移動(dòng)事件,窗口內(nèi)任意位置按下鼠標(biāo)左鍵拖動(dòng)窗口

    Qt獲取鼠標(biāo)移動(dòng)事件,窗口內(nèi)任意位置按下鼠標(biāo)左鍵拖動(dòng)窗口

    重寫窗口的兩個(gè)事件函數(shù)mousePressEvent和mouseMoveEvent即可: 在mousePressEvent 中,按下鼠標(biāo)左鍵時(shí),記錄窗口坐標(biāo),其中窗口坐標(biāo)的計(jì)算是由鼠標(biāo)事件獲取到鼠標(biāo)在整個(gè)屏幕中的坐標(biāo)(ev-globalpos()),然后再使用pos()獲取到鼠標(biāo)在窗口內(nèi)的相對(duì)位置,兩者之差就是窗口在整個(gè)屏幕上

    2024年02月12日
    瀏覽(31)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包