Flutter Combat 1: サイドバーを備えたメインインターフェイスを完成させる

1 週間の学習後、Notes 1 ~ 8 を読んだ多くの友人が自分の APP を書き始めました。この熱意に耐えられず、楽しく APP を開発したいと思いました。そこで、この記事から APP の真似から始めて、プロジェクトは 0 から始まり、各記事にコンテンツを追加して少しずつ APP を完成させ、各反復のコードは私のgitリポジトリにアップロードされます。

Flutterコード歴2週間以上の私にとって、開発経験が長いベテランほどコード構造の考え方が安定していないかもしれませんが、もし文章が悪いところがあればアドバイスをお願いします。

この記事で完了するタスク

上の図に示すように、この記事では HomePage を構築し、左上隅にサイドバー エントリを追加し、サイドバーから他のページに入ります。

最初の一歩

プロジェクトとフォルダーを作成します。vscode を開き、パスに移動して次のコマンドを入力します。

フラッター作成appbyflutter

図に示すようにプロジェクト ディレクトリを準備します。

プログラムディレクトリ

最初の記事の開発では使用するものはそれほど多くないので、まず、 APP のデフォルト画像を保存する画像ファイルをプロジェクト ディレクトリに追加するだけです。デフォルトの lib フォルダーの下にページ フォルダーを追加して、各ページを保存します。

第二段階

main.dart をAPP のエントリとしてのみ使用し、ページ エントリとルーティングの機能を想定します。

main.dart はページコードを記述しません

APP には複数のページがあるため、メンテナンスと管理を容易にするために、すべてのページ コードがページフォルダーに転送され、main.dart がAPP のメイン ページのエントリ、ルーティング、および一連の初期化 (自動ログイン、エントリーアニメーションなど)タスク。Vue や React の開発経験があるフロントエンドマスターならよく知っているはずです。そうすることで、メインプログラムとページを切り離すことができます。もちろん、この記事ではまだルーティングを使用していないため、ルーティング コードは書きませんルーティングについて学びたくない学生は、最初の APPまたはフロントエンドマスター英語読解を参照してください。

第三段階

ホームページ

最初のステップに示すように、home_page.dartother_page.dartという 2 つのファイルがページフォルダーに追加されます。ここで、 home_page.dartは APP のメイン ページ、other_page.dartは後で開発されるページです。

2 番目のステップの関数ではrunapp()、これが使用されていることに注意してくださいMaterialApp()。これは、プログラム APP のすべてのページ コントロールがデフォルトでマテリアルスタイルと一致することを意味します。

メイン ページはさまざまなコントロールを動的に参照するため、StatefulWidgetタイプはページの要件を満たすことができます。次の図からページ構造を分解します。

メインページの構造図

まず、図の左側にあるステートフル コントロールを見てくださいHomePage。これはページ全体の最上位パッケージであり、その中にScaffoldスキャフォールドが配置されています。これには、サイドバー ボタンコントロール、ページScaffoldに配置できる非常に豊富なプロパティがあります。DrawerタイトルAppBarコントロールとbodyパーツを追加するので、次のコードを貼り付けます。

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("CYC"), backgroundColor: Colors.redAccent,),  //头部的标题AppBar
      drawer: new Drawer(),  //侧边栏按钮Drawer
      body: new Center(  //中央内容部分body
        child: new Text('HomePage',style: new TextStyle(fontSize: 35.0),),
      ),
    );
  }
}

OK、左側のページは非常に簡単に構築できます。右側の図にある拡張されたサイドバーを実現するには、Drawerコントロールに何かを接続するだけで非常に簡単です。

サイドバー

まずサイドバーの構造を説明します。

サイドバーの構造図

  • サイドバー全体は上から下に口座番号の一覧といくつかの機能項目+区切り線があり、レイアウトコントロールを利用することが考えられやすいですListView

  • アカウント情報エリアには、アカウントアバター、ファンアバター、アカウントテキスト情報、背景画像があり、マテリアルコントロールライブラリのコントロールを使用してUserAccountsDrawerHeader実装できます。

  • 言うまでもなく、以下の機能リスト項目はListTitle適切に制御されており、分割線を直接Divider使用することができます。

そこで、new Drawer()次のコードを追加します。

//侧边栏填充内容
drawer: new Drawer(     //侧边栏按钮Drawer
        child: new ListView(
          children: <Widget>[
            new UserAccountsDrawerHeader(   //Material内置控件
              accountName: new Text('CYC'), //用户名
              accountEmail: new Text('[email protected]'),  //用户邮箱
              currentAccountPicture: new GestureDetector( //用户头像
                onTap: () => print('current user'),
                child: new CircleAvatar(    //圆形图标控件
                  backgroundImage: new NetworkImage('https://upload.jianshu.io/users/upload_avatars/7700793/dbcf94ba-9e63-4fcf-aa77-361644dd5a87?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240'),//图片调取自网络
                ),
              ),
              otherAccountsPictures: <Widget>[    //粉丝头像
                new GestureDetector(    //手势探测器,可以识别各种手势,这里只用到了onTap
                  onTap: () => print('other user'), //暂且先打印一下信息吧,以后再添加跳转页面的逻辑
                  child: new CircleAvatar(
                    backgroundImage: new NetworkImage('https://upload.jianshu.io/users/upload_avatars/10878817/240ab127-e41b-496b-80d6-fc6c0c99f291?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240'),
                  ),
                ),
                new GestureDetector(
                  onTap: () => print('other user'),
                  child: new CircleAvatar(
                    backgroundImage: new NetworkImage('https://upload.jianshu.io/users/upload_avatars/8346438/e3e45f12-b3c2-45a1-95ac-a608fa3b8960?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240'),
                    ),
                ),
              ],
              decoration: new BoxDecoration(    //用一个BoxDecoration装饰器提供背景图片
                image: new DecorationImage(
                  fit: BoxFit.fill,
                  // image: new NetworkImage('https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/lakes/images/lake.jpg')
                  //可以试试图片调取自本地。调用本地资源,需要到pubspec.yaml中配置文件路径
                  image: new ExactAssetImage('images/lake.jpg'),
                ),
              ),
            ),
            new ListTile(   //第一个功能项
              title: new Text('First Page'),
              trailing: new Icon(Icons.arrow_upward),
              onTap: () {
                Navigator.of(context).pop();
                Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new SidebarPage()));
              }
            ),
            new ListTile(   //第二个功能项
              title: new Text('Second Page'),
              trailing: new Icon(Icons.arrow_right),
              onTap: () {
                Navigator.of(context).pop();
                Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new SidebarPage()));
              } 
            ),
            new ListTile(   //第二个功能项
              title: new Text('Second Page'),
              trailing: new Icon(Icons.arrow_right),
              onTap: () {
                Navigator.of(context).pop();
                Navigator.of(context).pushNamed('/a');
              } 
            ),
            new Divider(),    //分割线控件
            new ListTile(   //退出按钮
              title: new Text('Close'),
              trailing: new Icon(Icons.cancel),
              onTap: () => Navigator.of(context).pop(),   //点击后收起侧边栏
            ),
          ],
        ),
      )

上記のコードではUserAccountsDrawerHeaderGestureDetectorBoxDecorationNetworkImageExactAssetImageなど、見慣れないコントロールが多数使用されていますが、ここでは一つずつ紹介しませんので、その特徴や使い方については公式の読解問題バンクを参照してください。私も最初は戸惑いました 強制的に、これらの組み込みコントロールを暗唱するだけで済みます。ページの複雑さの増加により、これらを取り出して個別にパッケージ化することも可能です。 。

画面の左端から右にスワイプするジェスチャーを試してみると、サイドバーを引き出すことができることがわかりましたか? もう一度右にスワイプしてサイドバーを閉じます。ジェスチャ イベントのコードは追加していません。これはDrawerコントロール自体のプロパティです。コントロールのマテリアルスタイル アニメーション効果と同じです。組み込みコントロールにも独自のデフォルト ジェスチャがあります。かすかに聞こえます。 ~ ネイティブ開発者はトイレで泣きながら気を失いました、ははは

4番目のステップ

機能ボタンはページジャンプをトリガーします。

まず、サブページを作成する必要があるため、pagesフォルダーの下に別のother_page.dartファイルを作成しましたHomePage.dartからother_page.dartにジャンプするには、 HomePage.dart内でother_page.dart を引用する必要もありますそれから:

ページファイルリファレンス

次に、other_page.dartにコードを入力します。

import 'package:flutter/material.dart';

class OtherPage extends StatelessWidget {

  final String pageText;    //定义一个常量,用于保存跳转进来获取到的参数

  OtherPage(this.pageText);    //构造函数,获取参数

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text(pageText),),    //将参数当作页面标题
      body: new Center(
        child: new Text('pageText'),
      ),
    );
  }
}

Flutter では、転送されるページでスペースを割り当てるために事前に定数を定義し、このパラメーターをコンストラクターに埋め込んで外部から渡されたパラメーター値をキャプチャする必要があります。

トリガージャンプ

クリックしてFirst PageSecond Pageの2 つのコントロールにジャンプするコードを追加しますListTile

new ListTile(
    title: new Text('First Page'),
    trailing: new Icon(Icons.arrow_upward),
    onTap: () {
        Navigator.of(context).pop();  //点击后收起侧边栏
        Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new OtherPage('First Page')));  //进入OtherPage页面,传入参数First Page
        }
 ),
new ListTile(
    title: new Text('Second Page'),
    trailing: new Icon(Icons.arrow_right),
    onTap: () {
        Navigator.of(context).pop();
        Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new OtherPage('Second Page')));
    } 
 ),

上記のコードのonTap()イベントにはNavigator.of(context).pop();、新しいページに入る前にサイドバーを折りたたむ必要があるという文があります。そのようなコードがないと、新しいページに入って戻ってきても、サイドバーが展開されたままになります。この経験は反人間的なものなので、書き留めてください。

要約する

製品の配置やデザインについて詳しく説明しなかったので、少し混乱しているかもしれませんが、多くのソーシャル アプリで一般的に使用されている上部 + 下部のタブ バー スタイルではなく、このサイドバー レイアウトが採用されているのはなぜですか?ご心配なく、次回実装予定です。サイドバーの利点は何ですか? スペースを節約するために、より重要な機能コントロール (音楽プレーヤーなど) を下部に配置する必要がある場合は、ページ切り替えロジックをサイドバーに配置するのが良い解決策です。この記事の内容は実は非常にシンプルで、主にいくつかの一般的なコントロールを紹介していますが、CSSを調整したり、バブリングイベントによる複雑なインタラクションロジックの実現について考える必要がないのがFlutterの魅力です。シンプルですが単純ではありません。読んでいただけると信じています。自分のアプリの開発に自信がつきました。今日はこれで終わりです。サポートありがとうございます。私のFlutter サークルに注目して、もっと貢献してください。あなたFlutter Chinese コミュニティ (公式 QQ グループ: 338252156)に参加して、一緒に成長することもできます。皆さん、ありがとう~

おすすめ

転載: blog.csdn.net/qq_27981847/article/details/88037441
おすすめ