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

Android Flutter實(shí)現(xiàn)自定義下拉刷新組件

 更新時(shí)間:2022年08月24日 08:34:38   作者:JulyYu  
在Flutter開發(fā)中官方提供了多平臺(tái)的下拉刷新組件供開發(fā)者使用。本文將改造一下這些組件,實(shí)現(xiàn)自定義的下拉刷新組件,感興趣的可以了解一下

前言

Flutter開發(fā)中官方提供了多平臺(tái)的下拉刷新組件供開發(fā)者使用,例如RefreshIndicatorCupertinoSliverRefreshControl分別適配AndroidiOS下拉刷新交互形態(tài)。但實(shí)際情況中這兩者使用情況卻不太相同在使用場景就存在差異,RefreshIndicator作為嵌套型下拉組件列表內(nèi)容作為它的child使用而CupertinoSliverRefreshControl是嵌入在Sliver列表中使用。同時(shí)對于交互設(shè)計(jì)來說一般更偏好RefreshIndicator下拉形式,通過下拉列表整體下移后透出拉下刷新組件樣式。

改造點(diǎn)

DIY下拉組件樣式

RefreshIndicator下拉組件樣式可能會(huì)在交互上不符合設(shè)計(jì)師要求。例如下拉過程中l(wèi)oading樣式出現(xiàn)交互是會(huì)和列表重合,實(shí)際需求可能是希望下拉過程中l(wèi)oading樣式和列表一樣同步下移出現(xiàn)。

因此修改原有的下拉刷新組件樣式構(gòu)建,構(gòu)建方法入?yún)⒅饕莚efreshState、pulledExtent、refreshTriggerPullDistance、refreshIndicatorExtent。原邏輯中組件偏量是固定不變_kActivityIndicatorMargin值,因此下拉組件樣式是直接顯示出來的。

調(diào)整方案根據(jù)pulledExtent下拉距離,默認(rèn)偏移下拉組件樣式自身高度加上下拉距離從而將偏移量從負(fù)方向向正方向展示。

 Widget buildRefreshIndicator(
      BuildContext context,
      RefreshIndicatorMode refreshState, //下拉狀態(tài)
      double pulledExtent, // 下拉實(shí)時(shí)距離
      double refreshTriggerPullDistance, // 下拉限制最大高度
      double refreshIndicatorExtent, // 下拉組件最大高度
      ) {
    return Container(
    color: Colors.deepOrange,
    child: Stack(
      clipBehavior: Clip.none,
      children: <Widget>[
        Positioned(
          top: -refreshIndicatorExtent + pulledExtent,
          left: 0.0,
          right: 0.0,
          //簡易的下拉樣式 忽略refreshState狀態(tài)
          child: Container(
            child: Text("我是下拉呀~~~~",style: TextStyle(color: Colors.white,fontSize: 20,),textAlign: TextAlign.center,),
          ),
        ),
      ],
    ),
  );
  }

刷新時(shí)機(jī)調(diào)整

RefreshIndicator下拉組件另外刷新觸發(fā)交互點(diǎn)也不是設(shè)計(jì)交互期望的邏輯,它的刷新觸發(fā)機(jī)制是只要下拉超過設(shè)置下拉距離并會(huì)觸發(fā)。但實(shí)際開發(fā)中可能并不希望當(dāng)?shù)竭_(dá)對應(yīng)點(diǎn)就去做刷新操作而是下拉到一定距離松手后才會(huì)觸發(fā),因此需要改造下拉刷新組件內(nèi)部的刷新機(jī)制。

原下拉刷新邏輯如下關(guān)鍵代碼所示,只要當(dāng)RefreshIndicatorMode.drag狀態(tài)下并且latestIndicatorBoxExtent > widget.refreshTriggerPullDistance時(shí)就會(huì)觸發(fā)下拉刷新方法。

  RefreshIndicatorMode transitionNextState() {
    RefreshIndicatorMode nextState;
。、、、 、、、 省略
      drag:
      case RefreshIndicatorMode.drag:
        if (latestIndicatorBoxExtent == 0) {
          return RefreshIndicatorMode.inactive;
        } else if (latestIndicatorBoxExtent < widget.refreshTriggerPullDistance) {
          return RefreshIndicatorMode.drag;
        } else {
          // 當(dāng)latestIndicatorBoxExtent > widget.refreshTriggerPullDistance就執(zhí)行
          if (widget.onRefresh != null) { //刷新邏輯執(zhí)行點(diǎn)
            HapticFeedback.mediumImpact();
            SchedulerBinding.instance.addPostFrameCallback((Duration timestamp) {
              refreshTask = widget.onRefresh()..whenComplete(() {
                if (mounted) {
                  setState(() => refreshTask = null);
                  refreshState = transitionNextState();
                }
              });
              setState(() => hasSliverLayoutExtent = true);
            });
          }
          return RefreshIndicatorMode.armed;
        }
        break;
      case RefreshIndicatorMode.armed:
        if (refreshState == RefreshIndicatorMode.armed && refreshTask == null) {
          goToDone();
          continue done;
        }

        if (latestIndicatorBoxExtent > widget.refreshIndicatorExtent) {
          return RefreshIndicatorMode.armed;
        } else {
          nextState = RefreshIndicatorMode.refresh;
        }
        continue refresh;
      refresh:
      case RefreshIndicatorMode.refresh:
        if (refreshTask != null) {
          return RefreshIndicatorMode.refresh;
        } else {
          goToDone();
        }
        continue done;
      	、、、、、省略
    }

    return nextState;
  }

弱希望下拉松手后判斷是否觸發(fā)刷新只修改RefreshIndicator下拉組件似乎無法直接滿足條件。因此需要結(jié)合手勢監(jiān)聽來完成,需要對整體框架代碼做一個(gè)調(diào)整。

增加Listener嵌套監(jiān)聽手勢抬起操作,獲取MagicSliverRefreshControlState(原是私有類放開為公有)判斷是否是超出下拉最小刷新間距,對內(nèi)部是否可刷新標(biāo)記進(jìn)行賦值操作。

GlobalKey<MagicSliverRefreshControlState> key = GlobalKey<MagicSliverRefreshControlState>();

Listener(
      child: CustomScrollView(
        physics: BouncingScrollPhysics(),
        slivers: <Widget>[
          MagicSliverRefreshControl(
            key: key,
            builder: buildRefreshIndicator,
            onRefresh: () async {
              print("<> SliverRefreshControl onRefresh start");
              await Future.delayed(Duration(seconds: 2),(){});
              print("<> SliverRefreshControl onRefresh end");
            },
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
                  (content, index) {
                return Common.getWidget(index);
              },
              childCount: 100,
            ),
          )
        ],
      ),
      onPointerUp: (event){ //判斷是否可刷新操作
        if(key?.currentState?.isCanRefreshAction() ?? false){
          key?.currentState?.canRefresh = true;
        }else{
          key?.currentState?.canRefresh = false;
        }
      },
    );

RefreshIndicator組件內(nèi)部增加一種新狀態(tài)RefreshIndicatorMode.over用來判斷是否刷新臨界狀態(tài),結(jié)合外部手勢抬手監(jiān)聽。當(dāng)下拉超出刷新最小間距且抬手放開判斷觸發(fā)刷新操作,over恢復(fù)到drag還是進(jìn)入armed都是通過以上條件來實(shí)現(xiàn)的,其他原邏輯保持不變。

switch (refreshState) {
      case RefreshIndicatorMode.inactive:
        if (latestIndicatorBoxExtent <= 0) {
          return RefreshIndicatorMode.inactive;
        } else {
          nextState = RefreshIndicatorMode.drag;
        }
        continue drag;
      drag:
      case RefreshIndicatorMode.drag:
        if (latestIndicatorBoxExtent == 0) {
          return RefreshIndicatorMode.inactive;
        }
        else if (latestIndicatorBoxExtent < widget.refreshTriggerPullDistance) {
          return RefreshIndicatorMode.drag;
        } else {
          return RefreshIndicatorMode.over; //增加一種狀態(tài) 表示下拉滿足刷新條件
        }
        break;
    	/// 進(jìn)入新狀態(tài)后結(jié)合抬手后是否可刷新標(biāo)記為判斷是進(jìn)入刷新方法還是回到拖拽狀態(tài)
      case RefreshIndicatorMode.over:
        if (latestIndicatorBoxExtent <= widget.refreshTriggerPullDistance) {
          if(canRefresh){
            canRefresh = false; //將刷新標(biāo)記置空復(fù)位
            if (widget.onRefresh != null) {
              HapticFeedback.mediumImpact();
              SchedulerBinding.instance.addPostFrameCallback((Duration timestamp) {
                refreshTask = widget.onRefresh()..whenComplete(() {
                  if (mounted) {
                    setState(() => refreshTask = null);
                    refreshState = transitionNextState();
                  }
                });
                setState(() => hasSliverLayoutExtent = true);
              });
            }
            return RefreshIndicatorMode.armed;
          }else{
            return RefreshIndicatorMode.drag;
          }
        }
        return RefreshIndicatorMode.over;
        break;

效果展示

具體代碼看這里

調(diào)整前

調(diào)整后

以上就是Android Flutter實(shí)現(xiàn)自定義下拉刷新組件的詳細(xì)內(nèi)容,更多關(guān)于Android Flutter下拉刷新的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android自定義Style實(shí)現(xiàn)方法

    Android自定義Style實(shí)現(xiàn)方法

    Android自定義Style實(shí)現(xiàn)方法,需要的朋友可以參考一下
    2013-06-06
  • android自定義WaveView水波紋控件

    android自定義WaveView水波紋控件

    這篇文章主要為大家詳細(xì)介紹了android自定義WaveView水波紋控件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Flutter 如何設(shè)置App的主色調(diào)與字體

    Flutter 如何設(shè)置App的主色調(diào)與字體

    App 開發(fā)過程中,肯定希望給用戶帶來一致的體驗(yàn),這其中最基礎(chǔ)的就是色調(diào)、字體保持一致。在 Flutter 中,可以設(shè)置全局的主題色調(diào)和字體,從而在其他頁面引用主色調(diào)和字體,實(shí)現(xiàn)頁面展示層面的一致。
    2021-05-05
  • Android9 清除最近進(jìn)程列表實(shí)現(xiàn)方法

    Android9 清除最近進(jìn)程列表實(shí)現(xiàn)方法

    這篇文章主要為大家介紹了Android9 清除最近進(jìn)程列表實(shí)現(xiàn)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Android 資源混淆的方案及注意事項(xiàng)

    Android 資源混淆的方案及注意事項(xiàng)

    資源混淆有助于減小包體積,也可以提高被反編譯后閱讀代碼的難度。還可以應(yīng)對一些安全檢測機(jī)構(gòu)對于資源混淆要求。本文基于微信的Android資源混淆工具,實(shí)現(xiàn)資源混淆
    2021-05-05
  • Android實(shí)現(xiàn)俄羅斯方塊

    Android實(shí)現(xiàn)俄羅斯方塊

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)俄羅斯方塊游戲 ,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Android實(shí)現(xiàn)ViewFlipper圖片動(dòng)畫滑動(dòng)

    Android實(shí)現(xiàn)ViewFlipper圖片動(dòng)畫滑動(dòng)

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)ViewFlipper圖片動(dòng)畫滑動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • flutter簡單使用案例

    flutter簡單使用案例

    這篇文章主要介紹了使用Flutter短視頻上滑翻頁效果,本篇介紹了?Flutter的翻頁組件PageView的使用,通過?PageView可以輕松實(shí)現(xiàn)類似短視頻的縱向上滑翻頁的效果,也可以實(shí)現(xiàn)橫向翻頁效果(如閱讀類軟件),需要的朋友可以參考下
    2023-05-05
  • Android 如何實(shí)現(xiàn)彈窗順序&優(yōu)先級控制

    Android 如何實(shí)現(xiàn)彈窗順序&優(yōu)先級控制

    這篇文章主要介紹了Android 如何實(shí)現(xiàn)彈窗順序&優(yōu)先級控制,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下
    2021-03-03
  • android書架效果實(shí)現(xiàn)原理與代碼

    android書架效果實(shí)現(xiàn)原理與代碼

    以前也模仿者ireader實(shí)現(xiàn)了書架的效果,但是那種是使用listview實(shí)現(xiàn)的,并不好用,今天介紹android書架效果實(shí)現(xiàn)方法
    2013-01-01

最新評論