flutter在导航栏处实现对两个列表的点击事件

原理:通过Function实现index的回调
导航栏代码

import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:oktoast/oktoast.dart';
import 'package:social_im/common/globalEventBus.dart';
import 'package:social_im/http/api.dart';
import 'package:social_im/http/rxhttp.dart';
import 'package:social_im/http/utils/NetUtils.dart';
import 'package:social_im/http/utils/response.dart';
import 'package:social_im/widget/loading_dialog.dart';
import '../../camera_picker/constants/constants.dart';
import '../../common/Global.dart';
import '../../common/colors.dart';
import '../../constant/dimens.dart';
import '../../http/net_callback.dart';
import '../../models/cloudCustomDataBean.dart';
import '../../utils/image_utile.dart';
import '../widget/myText.dart';
import 'MyDragBottle.dart';
import 'MyThrowBottle.dart';
import 'data/DriftBottleList.dart';
import '../../generated/l10n.dart';
import 'data/bottle_model.dart';
import 'dialog/chat_dialog.dart';

//我的瓶子导航栏
class MyBottleNav extends StatefulWidget {
  const MyBottleNav({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => MyBottleNavState();
}

class MyBottleNavState extends State<MyBottleNav>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;
  List<Chose> tabs = [];
  int currentIndex = 0;
  String inputCotent = '';
  List<AssetEntity> assetss = [];
  bool isScreening = false;

  //取屏幕最大宽度和高度
  final width = window.physicalSize.width;
  final height = window.physicalSize.height;
  DriftBottleList? driftBottleList;
  late StreamSubscription<OnCloseBottleRefresh> _onCloseBottleRefresh;

  @override
  void initState() {
    _getDriftBottleList();
    super.initState();
    tabs.add(Chose(title: S.current.bottle_thrown_bottles, position: 0));
    tabs.add(Chose(title: S.current.bottle_picked_bottles, position: 1));

    _tabController =
        TabController(length: tabs.length, vsync: this, initialIndex: 0);

    _tabController.addListener(() {
      if (_tabController.index.toDouble() == _tabController.animation!.value) {
        mySetState(() {
          currentIndex = _tabController.index;
        });
      }
    });

    _onCloseBottleRefresh = EventBusUtil.listen((event) {
      if (event.playType == CloudCustomDataBean.TYPE_DRIFT_BOTTLE) {
        _getDriftBottleList();
        if (mounted) {
          setState(() {});
        }
      }
    });
  }

  ///获取瓶子列表
  _getDriftBottleList() {
    showLoadingDialog();
    RxHttp<Response>()
      ..init()
      ..setBaseUrl(Api.BASE_API)
      ..setPath(Api.API_GET_DRIFT_BOTTLELIST)
      ..setCacheMode(CacheMode.FIRST_CACHE_THEN_REQUEST)
      ..setJsonTransFrom((p0) => Response.fromJson(json.decoder.convert(p0)))
      ..call(
          NetCallback(onNetFinish: (response) {
            dismissLoadingDialog();
            if (response.code == 200) {
              driftBottleList = DriftBottleList.fromJson(response.data);
            }
            if (mounted) {
              setState(() {});
            }
          }, onCacheFinish: (response) {
            if (response.code == 200) {
              driftBottleList = DriftBottleList.fromJson(response.data);
            }
            if (mounted) {
              setState(() {});
            }
          }, onNetError: (code) {
            dismissLoadingDialog();
            showToast('${S.current.network_error_tips}[$code]');
          }),
          server: Servers.microServices);
  }

  @override
  void dispose() {
    dismissLoadingDialog();
    _onCloseBottleRefresh.cancel();
    super.dispose();
  }

  mySetState(callBack) {
    if (mounted) {
      setState(() {
        callBack();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return AnnotatedRegion<SystemUiOverlayStyle>(
        value: SystemUiOverlayStyle.dark,
        child: Scaffold(
            resizeToAvoidBottomInset: false,
            body: Container(
                decoration: BoxDecoration(
                    image: DecorationImage(
                        image: ImageUtile.imageProvider(
                            'assets/images/bg_drift_my_bottle.png'),
                        fit: BoxFit.fill)),
                child: Column(children: [
                  addHeadView(),
                  Container(
                    color: Colors.transparent,
                    padding: const EdgeInsets.only(
                        bottom: 15, left: 8, right: 8, top: 27),
                    child: TabBar(
                        isScrollable: false,
                        indicatorWeight: 2.4,
                        indicatorSize: TabBarIndicatorSize.label,
                        indicatorColor: const Color(0xFF6EA6F5),
                        labelColor: const Color(0xFF6EA6F5),
                        labelStyle: const TextStyle(
                            fontSize: 18, fontWeight: FontWeight.w500),
                        labelPadding: const EdgeInsets.only(
                            left: 8, right: 8, bottom: 12),
                        unselectedLabelColor: const Color(0xFF1A1A1A),
                        unselectedLabelStyle: const TextStyle(
                            fontSize: 18, fontWeight: FontWeight.w500),
                        controller: _tabController,
                        tabs: tabs.map((chose) {
                          return Stack(
                            clipBehavior: Clip.none,
                            alignment: Alignment.topRight,
                            children: [
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(chose.title),
                                ],
                              ),
                              Positioned(
                                  right: -10,
                                  top: -10,
                                  child: showMessageNumView(chose.position == 0
                                      ? driftBottleList?.down_no_read_num ?? 0
                                      : driftBottleList?.up_no_read_num ?? 0))
                            ],
                          );
                        }).toList()),
                  ),
                  Expanded(
                      child: TabBarView(
                          controller: _tabController,
                          children: tabs.map((chose) {
                            switch (chose.position) {
                              case 0:
                                return MyThrowBottle(
                                  downList: driftBottleList?.downList ?? [],
                                  onItemClicked: (index) {
                                    showChatDialog(context, 2, index,
                                        chatDialogModel: ChatDialogModel(
                                            type: 0,
                                            bottleModel: driftBottleList
                                                    ?.downList![index] ??
                                                BottleModel()));
                                  },
                                );
                              case 1:
                                return MyDragBottle(
                                    upList: driftBottleList?.upList ?? [],
                                    onItemClicked: (index) {
                                      showChatDialog(context, 1, index,
                                          chatDialogModel: ChatDialogModel(
                                              type: 1,
                                              bottleModel: driftBottleList
                                                      ?.upList![index] ??
                                                  BottleModel()));
                                    });
                              default:
                                return Container();
                            }
                          }).toList()))
                ]))));
  }

  //头部按键
  Widget addHeadView() {
    return Container(
        padding: EdgeInsets.only(top: Global.topHeight + 10),
        color: Colors.transparent,
        child: GestureDetector(
          onTap: () {
            Navigator.pop(context);
          },
          child: Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              Container(
                  padding: const EdgeInsets.only(left: 16, right: 10),
                  child: ImageUtile.imageWidget(
                      'assets/images/icon_back@2x.png',
                      width: 24,
                      height: 24)),
              Text(S.current.bottle_my,
                  style: const TextStyle(
                      fontSize: Dimens.fontSize_16, color: Colors.black))
            ],
          ),
        ));
  }

  Widget showMessageNumView(messagesNum) {
    return Container(
        height: 18,
        child: messagesNum > 0
            ? PhysicalModel(
                color: Colors.transparent,
                borderRadius: BorderRadius.circular(9),
                clipBehavior: Clip.antiAlias,
                child: Container(
                    color: CommonColors.getColorFA6300,
                    padding: const EdgeInsets.fromLTRB(6, 1, 6, 1),
                    child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          ContentCenterText(
                              messagesNum > 99 ? '99+' : messagesNum.toString(),
                              11.0,
                              Colors.white)
                        ])))
            : null);
  }
}

///选择对象model
class Chose {
  const Chose({required this.title, required this.position});

  final String title;
  final int position;
}

重点部分,为什么要整合点击事件在导航栏这里,因为好看,好理解,逻辑比较顺,全局上点击

Expanded(
                      child: TabBarView(
                          controller: _tabController,
                          children: tabs.map((chose) {
                            switch (chose.position) {
                              case 0:
                                return MyThrowBottle(//扔瓶子界面
                                  downList: driftBottleList?.downList ?? [],//第一个参数
                                  onItemClicked: (index) {//第二个参数
                                    showChatDialog(context, 2, index,
                                        chatDialogModel: ChatDialogModel(
                                            type: 0,
                                            bottleModel: driftBottleList
                                                    ?.downList![index] ??
                                                BottleModel()));//当点击item时弹出弹窗
                                  },
                                );
                              case 1:
                                return MyDragBottle(//捞瓶子界面
                                    upList: driftBottleList?.upList ?? [],
                                    onItemClicked: (index) {
                                      showChatDialog(context, 1, index,
                                          chatDialogModel: ChatDialogModel(
                                              type: 1,
                                              bottleModel: driftBottleList
                                                      ?.upList![index] ??
                                                  BottleModel()));
                                    });
                              default:
                                return Container();
                            }
                          }).toList()))

捞瓶子代码

import 'dart:ui';

import 'package:flutter/material.dart';

import '../../common/colors.dart';
import '../../generated/l10n.dart';
import '../../utils/date_util.dart';
import '../widget/myText.dart';
import '../widget/splitLine.dart';
import 'data/bottle_model.dart';

//捡的瓶子
class MyDragBottle extends StatefulWidget {
  final List<BottleModel> upList;
  final Function(int index)? onItemClicked;

  const MyDragBottle({Key? key, required this.upList, this.onItemClicked})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => MyDragBottleState();
}

class MyDragBottleState extends State<MyDragBottle> {
  //取屏幕最大宽度和高度
  final width = window.physicalSize.width;
  final height = window.physicalSize.height;

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

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

  Widget showMessageNumView(messagesNum) {
    return Container(
        height: 18,
        child: messagesNum > 0
            ? PhysicalModel(
                color: Colors.transparent,
                borderRadius: BorderRadius.circular(9),
                clipBehavior: Clip.antiAlias,
                child: Container(
                    color: CommonColors.getColorFA6300,
                    padding: const EdgeInsets.fromLTRB(6, 1, 6, 1),
                    child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          ContentCenterText(
                              messagesNum > 99 ? '99+' : messagesNum.toString(),
                              11.0,
                              Colors.white)
                        ])))
            : null);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      color: Colors.transparent,
      home: widget.upList.isEmpty?Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            alignment: Alignment.center,
            child: Container(
                margin: const EdgeInsets.only(bottom: 120),
                child: Column(children: [
                  ContentText(S.current.bottle_no_data, 14.0,
                      CommonColors.getTextWeakColor()),
                  TopPadding(30),
                ])),
          )
        ],
      ):Scaffold(
        backgroundColor: Colors.transparent,
        body: Container(
          color: Colors.transparent,
          child: MediaQuery.removePadding(
              removeTop: true,
              context: context,
              child: widget.upList.isEmpty
                  ? Container()
                  : ListView.builder(
                      shrinkWrap: true,
                      itemCount: widget.upList.length,
                      itemBuilder: (BuildContext context, int index) {
                        BottleModel upList = widget.upList[index];
                        return GestureDetector(
                          onTap: () {
                            if (widget.onItemClicked != null) {
                              widget.onItemClicked!(index);
                            }
                          },
                          child: Stack(
                            alignment: Alignment.topRight,
                            children: [
                              if (index % 3 == 0)
                                Container(
                                  width: width,
                                  margin: const EdgeInsets.only(
                                      top: 16, left: 16, right: 16),
                                  padding: const EdgeInsets.only(
                                      left: 16, top: 16, bottom: 8, right: 16),
                                  decoration: BoxDecoration(
                                    color: const Color(0xFFF8F9FF),
                                    borderRadius: BorderRadius.circular(12),
                                    boxShadow: const [
                                      BoxShadow(
                                        color: Color(0xFFBCC0EE),
                                        blurRadius: 1,
                                      ),
                                    ],
                                  ),
                                  child: Column(
                                    mainAxisSize: MainAxisSize.max,
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      Text(
                                        upList.text!,
                                        style: const TextStyle(
                                            color: Color(0xFF333333),
                                            fontSize: 18),
                                      ),
                                      Container(
                                        margin: const EdgeInsets.only(top: 8),
                                        child: Text(
                                          DateUtil.formatDateMs(
                                              upList.downTime! * 1000,
                                              format: 'yyyy.MM.dd'),
                                          style: const TextStyle(
                                              color: Color(0xFF999999),
                                              fontSize: 12),
                                        ),
                                      )
                                    ],
                                  ),
                                ),
                              if (index % 3 == 1)
                                Container(
                                  width: width,
                                  margin: const EdgeInsets.only(
                                      top: 16, left: 16, right: 16),
                                  padding: const EdgeInsets.only(
                                      left: 16, top: 16, bottom: 8, right: 16),
                                  decoration: BoxDecoration(
                                    color: const Color(0xFFEDFAFF),
                                    borderRadius: BorderRadius.circular(12),
                                    boxShadow: const [
                                      BoxShadow(
                                        color: Color(0xFFBCE2F1),
                                        blurRadius: 1,
                                      ),
                                    ],
                                  ),
                                  child: Column(
                                    mainAxisSize: MainAxisSize.max,
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      Text(
                                        upList.text!,
                                        style: const TextStyle(
                                            color: Color(0xFF333333),
                                            fontSize: 18),
                                      ),
                                      Container(
                                        margin: const EdgeInsets.only(top: 8),
                                        child: Text(
                                          DateUtil.formatDateMs(
                                              upList.downTime! * 1000,
                                              format: 'yyyy.MM.dd'),
                                          style: const TextStyle(
                                              color: Color(0xFF999999),
                                              fontSize: 12),
                                        ),
                                      )
                                    ],
                                  ),
                                ),
                              if (index % 3 == 2)
                                Container(
                                  width: width,
                                  margin: const EdgeInsets.only(
                                      top: 16, left: 16, right: 16),
                                  padding: const EdgeInsets.only(
                                      left: 16, top: 16, bottom: 8, right: 16),
                                  decoration: BoxDecoration(
                                    color: const Color(0xFFFBFFF2),
                                    borderRadius: BorderRadius.circular(12),
                                    boxShadow: const [
                                      BoxShadow(
                                        color: Color(0xFFDBEBB6),
                                        blurRadius: 1,
                                      ),
                                    ],
                                  ),
                                  child: Column(
                                    mainAxisSize: MainAxisSize.max,
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      Text(
                                        upList.text!,
                                        style: const TextStyle(
                                            color: Color(0xFF333333),
                                            fontSize: 18),
                                      ),
                                      Container(
                                        margin: const EdgeInsets.only(top: 8),
                                        child: Text(
                                          DateUtil.formatDateMs(
                                              upList.downTime! * 1000,
                                              format: 'yyyy.MM.dd'),
                                          style: const TextStyle(
                                              color: Color(0xFF999999),
                                              fontSize: 12),
                                        ),
                                      )
                                    ],
                                  ),
                                ),
                              Positioned(
                                top: 7,
                                right: 15,
                                child: showMessageNumView(upList.noReadNum),
                              )
                            ],
                          ),
                        );
                      })),
        ),
      ),
    );
  }
}

回调的重点代码

class MyDragBottle extends StatefulWidget {
  final List<BottleModel> upList;
  final Function(int index)? onItemClicked;//定义一个可回调的对象,里面带一个参数,回调这个参数

  const MyDragBottle({Key? key, required this.upList, this.onItemClicked})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => MyDragBottleState();
}


ListView.builder(
                      shrinkWrap: true,
                      itemCount: widget.upList.length,
                      itemBuilder: (BuildContext context, int index) {
                        BottleModel upList = widget.upList[index];
                        return GestureDetector(
                          onTap: () {
                            if (widget.onItemClicked != null) {
                              widget.onItemClicked!(index);//当点击该item时回调该index给导航栏
                            }
                          },
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter中设置顶部导航栏可以使用AppBar组件。AppBar组件是Material Design中的一个标准组件,通常用于顶部导航栏或者应用栏。 以下是如何在Flutter中设置顶部导航栏的步骤: 1. 导入Material库:在Flutter中使用AppBar组件需要导入Material库,可以在文件开头添加以下代码: ``` import 'package:flutter/material.dart'; ``` 2. 创建AppBar:使用AppBar组件来创建顶部导航栏,可以在Scaffold组件中添加AppBar,如下所示: ``` Scaffold( appBar: AppBar( title: Text("My App"), ), body: Container(), ); ``` 在这个例子中,我们创建了一个标题为“My App”的AppBar。 3. 自定义AppBar:AppBar组件支持许多自定义属性,比如颜色、图标、菜单等。下面是一些常用的自定义属性: - backgroundColor:设置导航栏背景颜色 - actions:设置导航栏右侧的操作按钮 - leading:设置导航栏左侧的返回按钮 - elevation:设置导航栏的阴影大小 - title:设置导航栏标题 以下是一个自定义AppBar的例子: ``` Scaffold( appBar: AppBar( title: Text("My App"), backgroundColor: Colors.blue, actions: [ IconButton( icon: Icon(Icons.search), onPressed: (){}, ), IconButton( icon: Icon(Icons.more_vert), onPressed: (){}, ), ], leading: IconButton( icon: Icon(Icons.menu), onPressed: (){}, ), elevation: 4.0, ), body: Container(), ); ``` 在这个例子中,我们设置了导航栏的背景颜色为蓝色,右侧添加了两个操作按钮,左侧添加了一个菜单按钮,并且设置了导航栏的阴影大小为4.0。 通过以上步骤,你已经成功设置了顶部导航栏

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值