簡體   English   中英

點擊 AppBar 中的 IconButton 以顯示懸浮在 Scaffold 主體上的 TextField(帶有一個小部件,而不是兩個)

[英]Tap IconButton in AppBar to display TextField floating over Scaffold body (with one widget, not two)

有沒有辦法讓AppBar中的 Widget 中的框浮在Scaffold主體上方(上方)? 例如,如果我將我的搜索 Widget 放入Scaffold主體,當我的搜索IconButton被點擊時,這個TextField會出現並掛在它下面的內容上:

帶有搜索輸入框的搜索圖標

但是,理想情況下,我希望搜索圖標出現在AppBar (而不是Scaffold主體)中,然后在點擊時,我希望輸入框漂浮在Scaffold主體上。 如果我將 Search Widget 放入AppBar ,則TextField隱藏在Scaffold主體下,如下所示:

AppBar 中的搜索圖標在 Scaffold 后面溢出

如果你仔細看,在我點擊AppBar圖標下方但Scaffold主體上方的小邊距后,您實際上可以看到TextField

在 AppBar 和 Scaffold 之間點擊時的 TextField 邊框

因此,您可以看到TextField隱藏在Scaffold主體后面。

I discovered from the Flutter documentation that the Scaffold body puts its content below the AppBar and behind the floatingActionButton and drawer by design ( https://api.flutter.dev/flutter/material/Scaffold/body.html ). 但是,在這個用例中使用floatingActionButtondrawer會有點麻煩。

我想我可以將TextField放在一個單獨的小部件中並位於Scaffold主體中,並使用Provider / ChangeNotifierScaffold中的小部件進行通信,即AppBar中的IconButton已被點擊。 但是,這將組件邏輯分成了兩個地方,這看起來很混亂。 我希望有人可以用最佳實踐啟發我或讓我朝着正確的方向前進。

那么,有沒有合適的方法讓AppBar中的IconButton顯示一個漂浮在Scaffold主體上的TextField (這似乎是一個常見的用例。)

您可以為您的Scaffold > body使用Stack

在此處輸入圖像描述

完整源代碼:

import 'dart:math' show Random;

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(AppWidget());
}

class AppWidget extends StatelessWidget {
  const AppWidget({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => SearchModel(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(primaryColor: Color(0xfffedbd0)),
        title: 'Flutter Demo',
        home: HomePage(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<SearchModel>(
      builder: (context, searchModel, child) => Scaffold(
        appBar: AppBar(
          title: Text('SHRINE'),
          actions: [
            IconButton(
                icon: Icon(Icons.search, semanticLabel: 'search'),
                onPressed: () => searchModel.toggleVisibility()),
          ],
        ),
        body: Container(
          padding: EdgeInsets.all(16.0),
          alignment: Alignment.center,
          child: Search(),
        ),
      ),
    );
  }
}

class Search extends StatelessWidget {
  Search();

  @override
  Widget build(BuildContext context) {
    return Consumer<SearchModel>(builder: (context, searchModel, child) {
      return Stack(
        children: [
          GridView.count(
            crossAxisCount: 3,
            children: List.generate(
              30,
              (index) => Container(
                color: Color(0xaaaa0000 + 0xffffff ~/ (index + 1)),
              ),
            ),
          ),
          Positioned.fill(
            child: Align(
              alignment: Alignment.center,
              child: AnimatedOpacity(
                opacity: searchModel.isVisible ? 1.0 : 0.0,
                duration: Duration(milliseconds: 500),
                child: SizedBox(
                  width: 190.0,
                  height: 25.0,
                  child: TextField(
                    decoration: InputDecoration(
                      filled: true,
                      fillColor: Theme.of(context).primaryColor,
                      hintText: 'Enter a search term',
                      contentPadding: const EdgeInsets.symmetric(
                          horizontal: 8.0, vertical: 4.0),
                      enabledBorder: OutlineInputBorder(
                        borderSide: BorderSide(color: Colors.black),
                        borderRadius: BorderRadius.circular(25.7),
                      ),
                      focusedBorder: OutlineInputBorder(
                        borderSide: BorderSide(color: Colors.black),
                        borderRadius: BorderRadius.circular(25.7),
                      ),
                    ),
                    onChanged: (text) => searchModel.updateText(text),
                  ),
                ),
              ),
            ),
          ),
        ],
      );
    });
  }
}

class SearchModel extends ChangeNotifier {
  String text = '';
  bool isVisible = false;

  updateText(String newText) {
    text = newText;
    notifyListeners();
  }

  toggleVisibility() {
    isVisible = !isVisible;
    notifyListeners();
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM