Flutter开发日常练习-小猫咪杂货店(新增欢迎页,广告页和侧滑页面)

养小猫咪的伙伴来我的店铺逛逛吧!抖音商城搜索#早睡早起的猫咪小铺子

Flutter开发日常练习-小猫咪杂货店(新增动画和跳转抖音)_workersJiaDa的博客-CSDN博客URL Launcher是一个Flutter插件,它允许您的应用程序启动网络浏览器、地图应用程序、拨号器应用程序、邮件应用程序等。设定好每个图片的id,通过id作为 'Hero' 组件的标识,id不能重,否则会报错,在这两个页面中必须相同。给列表上的文字加了个缩放的提示动画,感觉很有意思,也有别的效果可以自己试一下。之前的练习加了个详情页面,然后跳转第三方页面抖音用户详情页面。跳转详情页添加了Hero的动画,共享元素过度。https://blog.csdn.net/zxc8890304/article/details/130317615

猫咪杂货铺项目持续更新中

APP设计思路的话改成猫咪百科好了,不会后端,数据源抓包,本地存着了

  1. 登录注册,个人信息添加本地存储修改
  2. 国际化版本
  3. 白天黑夜模式 
  4. 购物车物品删除
  5. 下单到订单支付流程
  6. 工具类整理(字体大小,字体颜色,主题颜色等)
  7. 图片库工具处理
  8. webview页面拦截优化
  9. 整体性能优化
  10. 打包处理

sp_util 是个不错的工具类

flutter_screenutil

在使用的时候需要注册宽度和高度

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
      designSize: const Size(375, 681),
      builder: (BuildContext context, Widget? child) =>  ChangeNotifierProvider(
        create: (context) => CarModel(),
        child: MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const StartPage(),
        ),
      ),
    );
  }
}

webview_flutter

添加webview跳转 

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebPage extends StatefulWidget {
  final String url;
  final String title;
  const WebPage({super.key, required this.url, required this.title});

  @override
  State<WebPage> createState() => _WebPageState(this.url, this.title);
}

class _WebPageState extends State<WebPage> {
  final String url;
  final String title;

  late final WebViewController controller;

  _WebPageState(this.url, this.title);
  @override
  void initState() {
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(const Color(0x00000000))
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            // Update loading bar.
          },
          onPageStarted: (String url) {},
          onPageFinished: (String url) {},
          onWebResourceError: (WebResourceError error) {},
          onNavigationRequest: (NavigationRequest request) {
            if (request.url.startsWith('https://pub.dev/')) {
              return NavigationDecision.prevent;
            }
            return NavigationDecision.navigate;
          },
        ),
      )
      ..loadRequest(Uri.parse(url));

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Column(
        children: [
          Expanded(
            child: WebViewWidget(controller: controller),
          ),
        ],
      ),
    );
  }
}

倒计时的广告,使用Timer来倒计时实现,

second_index是设定时间

设定时间自己修改,也可以服务端来修改

import 'dart:async';

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cat_1/pages/intro_page.dart';
import 'package:flutter_cat_1/tools/tools.dart';
import 'package:flutter_cat_1/web/web_page.dart';
import 'package:google_fonts/google_fonts.dart';

import '../main.dart';

class WelcomePage extends StatefulWidget {
  const WelcomePage({super.key});

  @override
  State<WelcomePage> createState() => _WelcomePageState();
}

class _WelcomePageState extends State<WelcomePage> {
  int second_index = 3;
  int timeIndex = 0;
  late Timer timer;

  @override
  void initState() {
    super.initState();
    timer = Timer.periodic(
      Duration(milliseconds: 50),
      (sd) {
        setState(() {
          timeIndex += 1;
          if (timeIndex % 20 == 0) {
            second_index -= 1;
          }
        });
        if (timeIndex >= 100) {
          _openMain();
        }
      },
    );
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        alignment: Alignment.center,
        children: <Widget>[
          Container(
            width: MediaQuery.of(context).size.width,
            height: MediaQuery.of(context).size.height,
            child: Image.asset(
              "assets/IMG_8050.png",
              fit: BoxFit.cover,
            ),
          ),
          Container(
            alignment: Alignment.bottomRight,
            child: Container(
              width: 50,
              height: 50,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(25),
              ),
              alignment: Alignment.center,
              margin: const EdgeInsets.all(25),
              child: GestureDetector(
                onTap: () {
                  _openMain();
                },
                child: Stack(
                  children: <Widget>[
                    Container(
                      alignment: Alignment.center,
                      child: CircularProgressIndicator(
                        value: timeIndex / 100,
                        strokeWidth: 2,
                      ),
                    ),
                    Container(
                      alignment: Alignment.center,
                      child: Text(
                        "跳过",
                        style: TextStyle(fontSize: 12,color: Colors.white,fontWeight: FontWeight.bold,),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
          Container(
            alignment: Alignment.center,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                RichText(
                  text: TextSpan(
                    text: "Flutter开发日常练习",
                    style: GoogleFonts.notoSerif(
                      color: Colors.black,
                      fontSize: 17,
                    ),
                    children: [
                      TextSpan(
                          text: "-小猫咪杂货店",
                          style: GoogleFonts.notoSerif(
                            color: Colors.black,
                            fontSize: 17,
                            // decoration: TextDecoration.underline,
                            // decorationColor: Colors.blue[800],
                          )),
                    ],
                  ),
                  textDirection: TextDirection.ltr,
                ),
                SizedBox(
                  height: 10,
                ),
                RichText(
                  text: TextSpan(
                    text: 'CSDN关注',
                    style: GoogleFonts.notoSerif(
                      fontSize: 17,
                      color: Colors.black,
                    ),
                    children: [
                      TextSpan(
                          text: 'workersJiaDa',
                          style: GoogleFonts.notoSerif(
                            fontSize: 17,
                            color: Colors.blue[800],
                            decoration: TextDecoration.underline,
                            decorationColor: Colors.blue[800],
                            fontWeight: FontWeight.bold,
                          ),
                          recognizer: TapGestureRecognizer()
                            ..onTap = () {
                              timer.cancel();
                              Navigator.of(context)
                                  .push(
                                    MaterialPageRoute(
                                      builder: (context) => WebPage(
                                          url:
                                              "https://blog.csdn.net/zxc8890304",
                                          title: "workersJiaDa的博客"),
                                    ),
                                  )
                                  .then((value) => reGetTimer());
                            }),
                    ],
                  ),
                ),
                SizedBox(
                  height: 10,
                ),
                RichText(
                  text: TextSpan(
                    text: '抖音商城搜索',
                    style: GoogleFonts.notoSerif(
                      color: Colors.black,
                      fontSize: 17,
                    ),
                    children: [
                      TextSpan(
                        text: "早睡早起的猫咪小铺子",
                        style: GoogleFonts.notoSerif(
                          fontSize: 17,
                          color: Colors.blue[800],
                          decoration: TextDecoration.underline,
                          decorationColor: Colors.blue[800],
                          fontWeight: FontWeight.bold,
                        ),
                        recognizer: TapGestureRecognizer()
                          ..onTap = () {
                            // timer.cancel();
                            launchURL('snssdk1128://user/profile/88486395468');
                          },
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  void _openMain() {
    timer.cancel();
    Navigator.pushAndRemoveUntil(
        context,
        MaterialPageRoute(
          builder: (context) => const IntroPage(),
        ),
        (route) => false);
  }

  void reGetTimer() {
    timer = Timer.periodic(
      Duration(milliseconds: 50),
      (sd) {
        setState(() {
          timeIndex += 1;
          if (timeIndex % 20 == 0) {
            second_index -= 1;
          }
        });
        if (timeIndex >= 100) {
          _openMain();
        }
      },
    );
  }
}

 欢迎页的话是

flutter_swiper_plus 

 非常简陋,简单的实现效果,要重新优化修改

添加了isFirst的判断,第一次打开APP才会显示,

之前做过国际化的项目,海外的需求是

只要是进入欢迎页不点跳过或者进入APP,每次进入APP都会再进入欢迎页面

这样做的话判断的条件需要重新修改一下

import 'dart:isolate';

import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cat_1/welcome/welcome_page.dart';
import 'package:flutter_swiper_plus/flutter_swiper_plus.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:sp_util/sp_util.dart';

class StartPage extends StatefulWidget {
  const StartPage({super.key});

  @override
  State<StartPage> createState() => _StartPageState();
}

class _StartPageState extends State<StartPage> {
  bool _isLogin = false;
  bool _isFirst = false;
  bool _islastPage = false;
  int pageInt = 1;
  final List _welcomeList = ["welcome_1.png", "welcome_2.png", "welcome_3.png"];

  @override
  void initState() {
    super.initState();
    _isFirst = SpUtil.getBool("first")!;

    if (_isFirst) {
      String? tokenStr = SpUtil.getString('token');
      _isLogin = (tokenStr == null || tokenStr.isEmpty) ? false : true;
      new Future.delayed(Duration(seconds: 0), () {
        Navigator.of(context).pushAndRemoveUntil(
            MaterialPageRoute(
              builder: (context) => WelcomePage(),
            ),
            (route) => false);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return 
    Container(
      color: Colors.white,
      height: ScreenUtil().screenHeight,
      child: Stack(
        children: [
          Swiper(
            itemBuilder: (context, index) {
              return Image.asset(
                "assets/${_welcomeList[index]}",
                fit: BoxFit.cover,
              );
            },
            itemCount: _welcomeList.length,
            loop: false,
            onIndexChanged: (index) {
              pageInt = index + 1;
              if (index == _welcomeList.length - 1) {
                setState(() {
                  _islastPage = true;
                });
              } else {
                setState(() {
                  _islastPage = false;
                });
              }
            },
          ),
          Container(
            width: 100,
            height: 40,
            alignment: Alignment.center,
            margin: EdgeInsets.only(
              left: ScreenUtil().screenWidth / 2 - 50,
              bottom: 40,
              top: ScreenUtil().screenHeight - 80,
              right: ScreenUtil().screenWidth / 2 - 50,
            ),
            child: Text(
              "$pageInt / 3",
              style: const TextStyle(
                  color: Colors.white,
                  fontSize: 30,
                  fontWeight: FontWeight.bold,
                  decoration: TextDecoration.none),
            ),
          ),
          Container(
            width: 100,
            height: 40,

            margin: EdgeInsets.only(
              left: ScreenUtil().screenWidth / 2 + 100,
              bottom: 40,
              top: ScreenUtil().screenHeight - 80,
              // right: ScreenUtil().screenWidth / 2 - 10,
            ),
            // decoration: BoxDecoration(
            //   border: Border.all(color: Colors.blue[900], width: 2),
            //   borderRadius: BorderRadius.circular(8),
            // ),
            child: Center(
              child: TextButton(
                onPressed:() => _jumpWelcome(),
                  // Navigator.push(context, MaterialPageRoute(
                  //   builder: (context) {
                       
                  //   },
                  // ));
              
                child: _islastPage
                    ? Text(
                        "立即进入",
                        style: GoogleFonts.notoSerif(
                            fontSize: 17,
                            color: Colors.blue[700],
                            fontWeight: FontWeight.bold),
                      )
                    : Text(
                        "跳过",
                        style: GoogleFonts.notoSerif(
                            fontSize: 17,
                            color: Colors.blue[700],
                            fontWeight: FontWeight.bold),
                      ),
              ),
            ),
          )
        ],
      ),
    );
  }

  _jumpWelcome() {
    SpUtil.putBool('first',true);
    String? tokenStr = SpUtil.getString("token");
    _isLogin = (tokenStr == null || tokenStr.isEmpty) ? false : true;
        Navigator.of(context).pushAndRemoveUntil(
            MaterialPageRoute(
              builder: (context) => WelcomePage(),
            ),
            (route) => false);
  }
}

 侧滑栏也是,比较简陋

import 'package:flutter/material.dart';
import 'package:flutter_cat_1/welcome/start_page.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

class DrawerPage extends StatelessWidget {
  const DrawerPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Drawer(
      elevation: 300,
      child: Stack(
        children: <Widget>[
          Column(
            children: <Widget>[
              UserAccountsDrawerHeader(
                accountName: Text("铲屎官铲屎官铲屎官"),
                accountEmail: Text("饲养员饲养员饲养员"),
                currentAccountPicture: CircleAvatar(
                  backgroundImage: AssetImage("assets/IMG_9406.png"),
                ),
                arrowColor: Colors.red,
                onDetailsPressed: () {},
                decoration: BoxDecoration(
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withOpacity(0.5),
                      offset: Offset(10, 10),
                      blurRadius: 45,
                      spreadRadius: 0.0,
                    ),
                  ],
                  image: DecorationImage(
                      image: AssetImage(
                        "assets/IMG_0259.png",
                      ),
                      fit: BoxFit.cover),
                ),
              ),
              Expanded(
                child: ListView(
                  padding: EdgeInsets.symmetric(vertical: 10),
                  children: <Widget>[
                    ListTile(
                      title: Text('个人中心'),
                    ),
                    Divider(),
                    ListTile(
                      title: Text('我的小猫咪'),
                    ),
                    Divider(),
                    ListTile(
                      title: Text("我的订单"),
                    ),
                    Divider(),
                    ListTile(
                      title: Text("关于我们"),
                    ),
                    Divider(),
                  ],
                ),
              ),
            ],
          ),
          Positioned(
            bottom: 20,
            right: 20,
            child: InkWell(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                crossAxisAlignment: CrossAxisAlignment.end,
                children: <Widget>[
                  GestureDetector(
                    onTap: () => Navigator.of(context).pushAndRemoveUntil(
                        MaterialPageRoute(
                      builder: (context) {
                        return StartPage();
                      },
                    ), (route) => false),
                    child: MenuItemButton(
                        child: Column(
                      children: const <Widget>[
                        Icon(
                          Icons.power_settings_new_outlined,
                          color: Colors.red,
                        ),
                        Text(
                          "退出登录",
                          style: TextStyle(
                            color: Colors.red,
                            fontSize: 12,
                          ),
                        ),
                      ],
                    )),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

DEMO地址 

GitHub - HelloJiada/flutter_cat_1Contribute to HelloJiada/flutter_cat_1 development by creating an account on GitHub.https://github.com/HelloJiada/flutter_cat_1.git

猜你喜欢

转载自blog.csdn.net/zxc8890304/article/details/130371789