flutter 泛型函數 不匹配問題

在StatefulWidget內使用泛型函數做爲數據交互方法時遇到相似 type '(String) => Null' is not a subtype of type '(dynamic) => void' 之類的問題:
git

可能不夠具象 來上代碼 :github

typedef TSwiperNormalItemBuilder<T> = Widget Function(T item);
class TSwiperNormal<T> extends StatefulWidget {
  final List<T> items;
  final TSwiperNormalItemBuilder<T> itemBuilder;
  final ValueChanged<T> onTapItem;
  TSwiperNormal({Key key,@required this.items,@required this.itemBuilder,this.onTapItem}):super(key: key);
  @override
  _TSwiperNormalState createState() => _TSwiperNormalState<T>();
}

class _TSwiperNormalState<T> extends State<TSwiperNormal> { 
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Swiper(
        itemBuilder: (c,i){
          if (widget.itemBuilder is TSwiperNormalItemBuilder<T>){
            return GestureDetector(
              onTap: (){
                if(widget.onTapItem != null)
                  widget.onTapItem(widget.items[i]);
              },
              child: widget.itemBuilder(widget.items[i]),
            );
          }else{
            return Container(color: Colors.red,);
          }
        },
        itemCount: widget.items.length,
      ),
    );
  }
}
複製代碼

而後盯着這行看半天 而後開始懷疑本身 懷疑人生 而且掉了兩根頭髮

typedef TSwiperNormalItemBuilder<T> = Widget Function(T item);
複製代碼

github 找到的:
This is a pretty subtle one - try changing from:
markdown

class _SearchScreenState<T> extends State<SearchScreen> 複製代碼

to
ide

class _SearchScreenState<T> extends State<SearchScreen<T>> 複製代碼

So the State needs to be State<SearchScreen> to not lose type information.
一語驚醒夢中人 極有多是_XXXState在繼承鏈上沒有獲得StatefulWidget傳過來的泛型類型
函數

立馬改爲oop

typedef TSwiperNormalItemBuilder<T> = Widget Function(T item);
class TSwiperNormal<T> extends StatefulWidget {
  final List<T> items;
  final TSwiperNormalItemBuilder<T> itemBuilder;
  final ValueChanged<T> onTapItem;
  TSwiperNormal({Key key,@required this.items,@required this.itemBuilder,this.onTapItem}):super(key: key);
  @override
  _TSwiperNormalState createState() => _TSwiperNormalState<T>();
}

class _TSwiperNormalState<T> extends State<TSwiperNormal<T>> { //這個地方必定注意接收來自StatefulWidget的泛型類型
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Swiper(
        itemBuilder: (c,i){
          if (widget.itemBuilder is TSwiperNormalItemBuilder<T>){
            return GestureDetector(
              onTap: (){
                if(widget.onTapItem != null)
                  widget.onTapItem(widget.items[i]);
              },
              child: widget.itemBuilder(widget.items[i]),
            );
          }else{
            return Container(color: Colors.red,);
          }
        },
        itemCount: widget.items.length,
      ),
    );
  }
}
複製代碼

代碼生成等插件、快捷鍵當然提示開發效率,但也要時刻警戒他們給你挖坑
ps:其實主要問題仍是我本身 一開始沒想加泛型 因此代碼也沒自動生成這個T 被本身氣到變形ui

相關文章
相關標籤/搜索