flutter开发实战-下拉刷新继续下拉路由进入活动页面实现

flutter开发实战-下拉刷新继续下拉路由进入活动页面实现

很多应用都有首页通过下拉刷新,继续下拉进入新的活动会场进入方式。在Flutter中,也可以通过pull_to_refresh来实现控制刷新页,继续下拉进入新的活动会场页面

一、引入pull_to_refresh

在工程的pubspec.yaml中引入插件

  pull_to_refresh: ^2.0.0
    

在pull_to_refresh中有enableTwoLevel、enablePullDown、enablePullUp属性。
onRefresh:当调用下拉刷新的回调onRefresh,当拉取数据完成后可以调用_refreshController1.refreshCompleted()。
onLoading:当调用上拉加载数据的时候的回调onLoading,获取数据完成后调用_refreshController1.loadComplete();
header:下拉刷新显示的headerWidget
footer:上拉加载显示的footerWidget

插件example示例如下

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'
    hide RefreshIndicator, RefreshIndicatorState;
import 'package:flutter/widgets.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

/*
   there two example implements two level,
   the first is common,when twoRefreshing,header will follow the list to scrollDown,when closing,still follow
   list move up,
   the second example use Navigator and keep offset when twoLevel trigger,
   header can use ClassicalHeader to implments twoLevel,it provide outerBuilder(1.4.7)
   important point:
   1. open enableTwiceRefresh bool ,default is false
   2. _refreshController.twiceRefreshComplete() can closing the two level
*/
class TwoLevelExample extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _TwoLevelExampleState();
  }
}

class _TwoLevelExampleState extends State<TwoLevelExample> {
  RefreshController _refreshController1 = RefreshController();
  RefreshController _refreshController2 = RefreshController();
  int _tabIndex = 0;

  @override
  void initState() {
    // TODO: implement initState
    _refreshController1.headerMode?.addListener(() {
      setState(() {});
    });
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _refreshController1.position?.jumpTo(0);
      setState(() {});
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return RefreshConfiguration.copyAncestor(
      context: context,
      enableScrollWhenTwoLevel: true,
      maxOverScrollExtent: 120,
      child: Scaffold(
        bottomNavigationBar: !_refreshController1.isTwoLevel
            ? BottomNavigationBar(
          currentIndex: _tabIndex,
          onTap: (index) {
            _tabIndex = index;
            if (mounted) setState(() {});
          },
          items: [
            BottomNavigationBarItem(
                icon: Icon(Icons.add), label: "二级刷新例子1"),
            BottomNavigationBarItem(
                icon: Icon(Icons.border_clear), label: "二级刷新例子2")
          ],
        )
            : null,
        body: Stack(
          children: <Widget>[
            Offstage(
              offstage: _tabIndex != 0,
              child: LayoutBuilder(
                builder: (_, c) {
                  return SmartRefresher(
                    header: TwoLevelHeader(
                      textStyle: TextStyle(color: Colors.white),
                      displayAlignment: TwoLevelDisplayAlignment.fromTop,
                      decoration: BoxDecoration(
                        image: DecorationImage(
                            image: AssetImage("images/secondfloor.jpg"),
                            fit: BoxFit.cover,
                            // 很重要的属性,这会影响你打开二楼和关闭二楼的动画效果
                            alignment: Alignment.topCenter),
                      ),
                      twoLevelWidget: TwoLevelWidget(),
                    ),
                    child: CustomScrollView(
                      physics: ClampingScrollPhysics(),
                      slivers: <Widget>[
                        SliverToBoxAdapter(
                          child: Container(
                            child: Scaffold(
                              appBar: AppBar(),
                              body: Column(
                                children: <Widget>[
                                  TextButton(
                                    onPressed: () {
                                      Navigator.of(context).pop();
                                    },
                                    child: Text("点击这里返回上一页!"),
                                  ),
                                  TextButton(
                                    onPressed: () {
                                      _refreshController1.requestTwoLevel();
                                    },
                                    child: Text("点击这里打开二楼!"),
                                  )
                                ],
                              ),
                            ),
                            height: 500.0,
                          ),
                        )
                      ],
                    ),
                    controller: _refreshController1,
                    enableTwoLevel: true,
                    enablePullDown: true,
                    enablePullUp: true,
                    onLoading: () async {
                      await Future.delayed(Duration(milliseconds: 2000));
                      _refreshController1.loadComplete();
                    },
                    onRefresh: () async {
                      await Future.delayed(Duration(milliseconds: 2000));
                      _refreshController1.refreshCompleted();
                    },
                    onTwoLevel: (bool isOpen) {
                      print("twoLevel opening:" + isOpen.toString());
                    },
                  );
                },
              ),
            ),
            Offstage(
              offstage: _tabIndex != 1,
              child: SmartRefresher(
                header: ClassicHeader(),
                child: CustomScrollView(
                  physics: ClampingScrollPhysics(),
                  slivers: <Widget>[
                    SliverToBoxAdapter(
                      child: Container(
                        child: TextButton(
                          onPressed: () {
                            Navigator.of(context).pop();
                          },
                          child: Text("点击这里返回上一页!"),
                        ),
                        color: Colors.red,
                        height: 680.0,
                      ),
                    )
                  ],
                ),
                controller: _refreshController2,
                enableTwoLevel: true,
                onRefresh: () async {
                  await Future.delayed(Duration(milliseconds: 2000));
                  _refreshController2.refreshCompleted();
                },
                onTwoLevel: (bool isOpen) {
                  if (isOpen) {
                    print("Asd");
                    _refreshController2.position?.hold(() {});
                    Navigator.of(context)
                        .push(MaterialPageRoute(
                        builder: (c) => Scaffold(
                          appBar: AppBar(),
                          body: Text("二楼刷新"),
                        )))
                        .whenComplete(() {
                      _refreshController2.twoLevelComplete(
                          duration: Duration(microseconds: 1));
                    });
                  }
                },
              ),
            )
          ],
        ),
      ),
    );
  }
}

class TwoLevelWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      decoration: BoxDecoration(
        image: DecorationImage(
            image: AssetImage("images/secondfloor.jpg"),
            // 很重要的属性,这会影响你打开二楼和关闭二楼的动画效果,关联到TwoLevelHeader,如果背景一致的情况,请设置相同
            alignment: Alignment.topCenter,
            fit: BoxFit.cover),
      ),
      child: Stack(
        children: <Widget>[
          Center(
            child: Wrap(
              children: <Widget>[
                TextButton(
                  onPressed: () {},
                  child: Text("登陆"),
                ),
              ],
            ),
          ),
          Container(
            height: 60.0,
            child: GestureDetector(
              child: Icon(
                Icons.arrow_back_ios,
                color: Colors.white,
              ),
              onTap: () {
                SmartRefresher.of(context)?.controller.twoLevelComplete();
              },
            ),
            alignment: Alignment.bottomLeft,
          ),
        ],
      ),
    );
  }
}
    

如果在下拉进入活动页面需要路由跳转,可以在onTwoLevel回调中调用路由跳转

if (isOpen) {
                    print("Asd");
                    _refreshController2.position?.hold(() {});
                    Navigator.of(context)
                        .push(MaterialPageRoute(
                        builder: (c) => Scaffold(
                          appBar: AppBar(),
                          body: Text("二楼刷新"),
                        )))
                        .whenComplete(() {
                      _refreshController2.twoLevelComplete(
                          duration: Duration(microseconds: 1));
                    });
                  }
    

二、下拉进入活动页面实现路由跳转

下拉一定距离后,通过路由跳转进入相应的活动页面,这里是onTwoLevel回调中push到指定页面

onTwoLevel: (bool isOpen) async {
                  print("aaa twoLevel opening:" + isOpen.toString());
                  if (isOpen) {
                    Navigator.of(context)
                        .push(MaterialPageRoute(builder: (BuildContext context) {
                      return TopFloorPage();
                    })).then((value){
                      print("onTwoLevel push then");
                    }).whenComplete(() {
                      print("onTwoLevel push whenComplete");
                      refreshController.twoLevelComplete(
                          duration: Duration(microseconds: 1));
                    });
                  } else {
                    refreshController.position?.jumpTo(0);
                  }
                },
    

下拉进入活动页面实现路由跳转完整代码如下

second_floor_page.dart

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_app_demolab/display/pull_refresh_helper.dart';
import 'package:flutter_app_demolab/display/top_floor_page.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

class SlideTopRouteBuilder extends PageRouteBuilder {
  final Widget page;

  SlideTopRouteBuilder(this.page)
      : super(
            pageBuilder: (context, animation, secondaryAnimation) => page,
            transitionDuration: Duration(milliseconds: 800),
            transitionsBuilder:
                (context, animation, secondaryAnimation, child) =>
                    SlideTransition(
                      position: Tween<Offset>(
                              begin: Offset(0.0, -1.0), end: Offset(0.0, 0.0))
                          .animate(CurvedAnimation(
                              parent: animation, curve: Curves.fastOutSlowIn)),
                      child: child,
                    ));
}

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

  @override
  State<SecondFloorPage> createState() => _SecondFloorPageState();
}

class _SecondFloorPageState extends State<SecondFloorPage> {
  final RefreshController _refreshController =
      RefreshController(initialRefresh: false);

  RefreshController get refreshController => _refreshController;

  final ScrollController _scrollController = ScrollController();

  double _height = 200;

  bool _showTopBtn = false;

  ScrollController get scrollController => _scrollController;

  bool get showTopBtn => _showTopBtn;

  scrollToTop() {
    _scrollController.animateTo(0,
        duration: Duration(milliseconds: 300), curve: Curves.easeOutCubic);
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    // _scrollController.addListener(() {
    //   if (_scrollController.offset > _height && !_showTopBtn) {
    //     _showTopBtn = true;
    //     setState(() {});
    //   } else if (_scrollController.offset < _height && _showTopBtn) {
    //     _showTopBtn = false;
    //     setState(() {});
    //   }
    // });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SecondFloor'),
      ),
      body: MediaQuery.removePadding(
        context: context,
        removeTop: false,
        child: Builder(
          builder: (_) {
            return RefreshConfiguration.copyAncestor(
              context: context,
              twiceTriggerDistance: kHomeRefreshHeight - 15,
              maxOverScrollExtent: kHomeRefreshHeight,
              headerTriggerDistance:
                  80 + MediaQuery.of(context).padding.top / 3,
              child: SmartRefresher(
                controller: _refreshController,
                header: HomeRefreshHeader(),
                enableTwoLevel: true,
                onTwoLevel: (bool isOpen) async {
                  print("aaa twoLevel opening:" + isOpen.toString());
                  if (isOpen) {
                    Navigator.of(context)
                        .push(MaterialPageRoute(builder: (BuildContext context) {
                      return TopFloorPage();
                    })).then((value){
                      print("onTwoLevel push then");
                    }).whenComplete(() {
                      print("onTwoLevel push whenComplete");
                      refreshController.twoLevelComplete(
                          duration: Duration(microseconds: 1));
                    });
                  } else {
                    refreshController.position?.jumpTo(0);
                  }
                },
                footer: RefresherFooter(),
                enablePullDown: true,
                onRefresh: () async {
                  await Future.delayed(Duration(milliseconds: 300));
                  refreshController.refreshCompleted();
                },
                onLoading: () async {
                  await Future.delayed(Duration(milliseconds: 300));
                  refreshController.loadComplete();
                },
                enablePullUp: true,
                child: ListView.builder(
                  controller: _scrollController,
                  itemBuilder: (context, index) {
                    return Card(
                      child: Container(
                        alignment: Alignment.center,
                        height: 80,
                        child: Text('${index + 1}'),
                      ),
                    );
                  },
                  itemCount: 80,
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

    

top_floor_page.dart

import 'package:flutter/material.dart';

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

  @override
  State<TopFloorPage> createState() => _TopFloorPageState();
}

class _TopFloorPageState extends State<TopFloorPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('二楼页面'),
      ),
      body: Center(
        child: Text('二楼页面详情'),
      ),
    );
  }
}
    

pull_refresh_helper.dart

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app_demolab/display/top_floor_page.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

const double kHomeRefreshHeight = 180.0;


class HomeSecondFloorOuter extends StatelessWidget {
  final Widget child;

  HomeSecondFloorOuter(this.child, {super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      height: kHomeRefreshHeight + MediaQuery.of(context).padding.top + 20,
      width: MediaQuery.of(context).size.width,
      child: Stack(
        children: <Widget>[
          CachedNetworkImage(
            imageUrl: "https://c-ssl.dtstatic.com/uploads/blog/202404/28/LySGQjOntqjzaBW.thumb.1000_0.jpeg",
            fit: BoxFit.cover,
            height: kHomeRefreshHeight + MediaQuery.of(context).padding.top + 20,
            width: MediaQuery.of(context).size.width,
          ),
          Align(
            alignment: Alignment.bottomCenter,
            child: Text('跌跌撞撞中,依旧热爱这个世界.',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 22,
                  fontWeight: FontWeight.bold,
                )),
          ),
          Align(alignment: Alignment(0, 0.85), child: child),
        ],
      ),
      alignment: Alignment.bottomCenter,
    );
  }
}

/// 由于app不管明暗模式,都是有底色
/// 所以将indicator颜色为亮色
class ActivityIndicator extends StatelessWidget {
  final double? radius;
  final Brightness? brightness;

  ActivityIndicator({this.radius, this.brightness});

  @override
  Widget build(BuildContext context) {
    return Theme(
        data: ThemeData(
          cupertinoOverrideTheme: CupertinoThemeData(brightness: brightness),
        ),
        child: CupertinoActivityIndicator(radius: radius ?? 10));
  }
}

/// 首页列表的header
class HomeRefreshHeader extends StatelessWidget {
  const HomeRefreshHeader({super.key});

  @override
  Widget build(BuildContext context) {
    var strings = RefreshLocalizations.of(context)?.currentLocalization ??
        EnRefreshString();
    return ClassicHeader(
      canTwoLevelText: "松开进入二楼",
      textStyle: TextStyle(color: Colors.white),
      outerBuilder: (child) => HomeSecondFloorOuter(child),
      twoLevelView: Container(),
      height: 70 + MediaQuery.of(context).padding.top / 3,
      refreshingIcon: ActivityIndicator(brightness: Brightness.dark),
      releaseText: strings.canRefreshText,
    );
  }
}

/// 通用的footer
///
/// 由于国际化需要context的原因,所以无法在[RefreshConfiguration]配置
class RefresherFooter extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ClassicFooter(
//      failedText: S.of(context).loadMoreFailed,
//      idleText: S.of(context).loadMoreIdle,
//      loadingText: S.of(context).loadMoreLoading,
//      noDataText: S.of(context).loadMoreNoData,
    );
  }
}

    

最后需要在MaterialApp中配置RefreshConfiguration

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return RefreshConfiguration(
      hideFooterWhenNotFull: true, //列表数据不满一页,不触发加载更多
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          // This is the theme of your application.
          //
          // Try running your application with "flutter run". You'll see the
          // application has a blue toolbar. Then, without quitting the app, try
          // changing the primarySwatch below to Colors.green and then invoke
          // "hot reload" (press "r" in the console where you ran "flutter run",
          // or simply save your changes to "hot reload" in a Flutter IDE).
          // Notice that the counter didn't reset back to zero; the application
          // is not restarted.
          primarySwatch: Colors.blue,
        ),
        home: const MyHomePage(title: 'Flutter Demo Home Page'),
      ),
    );
  }
}
    

效果图如下

在这里插入图片描述

三、小结

flutter开发实战-下拉刷新继续下拉路由进入活动页面实现

学习记录,每天不停进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/663623.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

svg实现一个圆形以及方形的环形进度条

1. svg实现圆形进度条 效果图&#xff1a; 1. 写个假接口&#xff1a; let res {curLegendList: [{ progress: "87", name: "进度1",color:"#00fe41" },{ progress: "66", name: "进度2" ,color:"orange"},{ p…

HarmonyOS鸿蒙学习笔记(25)相对布局 RelativeContainer详细说明

RelativeContainer 简介 前言核心概念官方实例官方实例改造蓝色方块改造center 属性说明参考资料 前言 RelativeContainer是鸿蒙的相对布局组件&#xff0c;它的布局很灵活&#xff0c;可以很方便的控制各个子UI 组件的相对位置&#xff0c;其布局理念有点类似于android的约束…

OpenPCDet

一.简介 源码链接&#xff1a; https://github.com/open-mmlab/OpenPCDethttps://github.com/open-mmlab/OpenPCDet OpenPCDet 是一套基于PyTorch实现的点云3D目标检测代码库。&#xff08;也是个框架&#xff09; 设计思想&#xff1a;点云数据集&#xff08;KITTI、NuSce…

pytorch学习笔记2

首先如果遇到conda找不到包&#xff0c;pip老是超时的情况建议添加一下镜像源 conda的 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ cond…

【C++ | 类】类和对象

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a; 本文未经允许…

收银系统源码-千呼新零售2.0【智慧供应链】

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货等连锁店使用。 详细介绍请查看下…

为什么String要被设置为不可变的

为什么设置为不可变的 Java 中将 String 设计为不可变的原因有多个&#xff0c;主要涉及到安全、效率、同步和设计哲学 缓存 在我们的JVM中&#xff0c;单独开辟了一个空间来存储Java字符串&#xff0c;就是字符串池 String s1"1234"; String s2"766"; …

iPhone快捷指令之九宫格照片(三)

说明&#xff1a;这个是经过前两章的摸索&#xff0c;在我搞明白怎么接共享表单里的数据和会使用变量后&#xff0c;制作出来的终极九宫格照片指令&#xff0c;同一个指令在主屏幕里点击可以选择图片做九宫格图片&#xff1b;在相册里选择图片&#xff0c;点击分享按钮&#xf…

Kotlin 2.0 重磅发布! 性能提升!新功能上线!开发者必看!

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

C++ 关系运算

一 关系运算 二 关系运算符 三 关系表达式 四 关系表达式的值-------逻辑值 五 运算的优先级 六 注意事项 七 总结

【ai】pycharm安装github copilot解决chat一直无法初始化loading的问题

github copilot github-copilot 插件安装后:在工具里找到它 底部也有它 侧边可以chat 更新到2014.1.2copilot 也是最新但是chat 就是一直无法loading成功显示一直在初始化copilot中fix :

Python | Leetcode Python题解之第119题杨辉三角II

题目&#xff1a; 题解&#xff1a; class Solution:def getRow(self, rowIndex: int) -> List[int]:row [1, 1]if rowIndex < 1:return row[:rowIndex 1]elif rowIndex > 2:for i in range(rowIndex - 1):row [row[j] row[j 1] for j in range(i 1)]row.inser…

一、大模型推理

https://github.com/hiyouga/LLaMA-Factory/blob/main/README_zh.md https://github.com/hiyouga/LLaMA-Factory/blob/main/examples/README_zh.md 安装 v7.1 https://github.com/hiyouga/LLaMA-Factory/releases/tag/v0.7.1 git clone --depth 1 https://github.com/hiyoug…

自动化安装Nginx

1. 指定版本号和用户&#xff1b; 2. 确定安装目录&#xff1b; 3. 确定安装编译模块&#xff1b; 4. 安装相关依赖&#xff1b; 5. 下载源码包并解压&#xff1b; 6. 编译安装&#xff1b; 7. 文件授权及临时文件清理。 #!/bin/bash# 用户输入的Nginx版本号NGIN…

基于深度学习的端到端语音识别时代

随着深度学习的发展&#xff0c;语音识别由DNN-HMM时代发展到基于深度学习的“端到端”时代&#xff0c;这个时代的主要特征是代价函数发生了变化&#xff0c;但基本的模型结构并没有太大变化。总体来说&#xff0c;端到端技术解决了输入序列长度远大于输出序列长度的问题。 采…

【深度学习基础】使用Pytorch搭建DNN深度神经网络与手写数字识别

目录 写在开头 一、DNN的搭建 问题描述与数据集 神经网络搭建 模型训练 模型评估 模型复用 二、手写数字识别 任务描述 数据集 神经网络搭建 模型训练 模型评估 写在最后 写在开头 本文将介绍如何使用PyTorch框架搭建深度神经网络模型。实现模型的搭建、模…

《HelloGitHub》第 98 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、…

PostgreSQL 远程登录postgres用户不需要密码?免密登录权限设置

PostgreSQL 安装之后&#xff0c;发现登录postgres用户时不需要密码。原因配置远程IP时&#xff0c;IP 地址对应的 method 设置成了 trust。 今天安全测试反馈&#xff0c;pgsql有弱口令问题&#xff0c;于是上去改了pgsql的密码&#xff0c;结果问题还没解决。查看了具体的问…

PyQt5开发笔记:1.环境搭建与界面美化

推荐视频教程&#xff1a; https://www.bilibili.com/video/BV1LT4y1e72X?p23&vd_source7ab611f3afb3d469faad93d3996f99ba 一、打开网址&#xff0c;点击下载 https://build-system.fman.io/qt-designer-download 下载后&#xff0c;点开exe 不推荐&#xff1a;http…

VSCODE 常用快捷键

快捷按键 注释 CTRL /CTRL KSHIFT ALT A取消注释 CTRL /CTRL KSHIFT ALT A搜索文件 Ctrl P移动到某一行 Ctrl g打开一个新窗口 Ctrl Shift N关闭窗口 Ctrl Shift W新建文件 Ctrl N文件间切换 Ctrl Tab全部文件搜索 Ctrl Shift F全屏 F11 打开文件出现中文乱码 文件右下角…