实现此主屏幕的最佳方法是什么?

问题描述

我想为我的 Flutter 应用创建一个主页。我使用了网络上的模板,但不幸的是我没有按照我在图片中勾画的方式来理解它。也许有人可以帮助我

sketch / result

不幸的是,我确信我不能做得更好:-/,希望它与左边的完全一样(图标和颜色不是那么重要)

我使用论坛中的此链接作为应用栏的模板,但在插入时遇到了困难^^ Custom AppBar Flutter

我也从论坛的某个地方获得了 BottomNavigationBar 的代码,但我认为这无论如何都不适合我的目的。由于我不喜欢点击时的这种收缩效果,所以边缘的两个箭头按钮在按下时应该会弹回而不是保持按下状态,因为它们应该代表前后功能......

这是我完整的 main.dart

import 'package:Flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      themeMode: ThemeMode.light,theme: ThemeData(
          primaryColor: Color(0xFF34445c),primaryColorBrightness: Brightness.light,brightness: Brightness.light,primaryColorDark: Colors.black,canvasColor: Color(0xFFCECECE),appBarTheme: AppBarTheme(brightness: Brightness.light)),darkTheme: ThemeData(
          primaryColor: Colors.black,primaryColorBrightness: Brightness.dark,primaryColorLight: Colors.black,brightness: Brightness.dark,indicatorColor: Colors.white,canvasColor: Colors.black,appBarTheme: AppBarTheme(brightness: Brightness.dark)),home: MyHomePage(),);
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key,this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful,meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _selectedItemColor = Colors.white;
  final _unselectedItemColor = Colors.white30;
  final _selectedBgColor = Color(0xFF293749);
  final _unselectedBgColor = Color(0xFF34445c);
  int _selectedindex = 0;
  static const TextStyle optionStyle =
  TextStyle(fontSize: 15,fontWeight: FontWeight.normal);
  static const List<Widget> _widgetoptions = <Widget>[
    Text(
      'Index 0: ZURÜCK',style: optionStyle,),Text(
      'Index 1: FAVORITES',Text(
      'Index 2: KOMMENTARE / LÖSCHEN',Text(
      'Index 3: ABOUT-US',Text(
      'Index 4: WEITER',];

  void _onItemTapped(int index) {
    setState(() {
      _selectedindex = index;
    });
  }

  Color _getBgColor(int index) =>
      _selectedindex == index ? _selectedBgColor : _unselectedBgColor;

  Color _getItemColor(int index) =>
      _selectedindex == index ? _selectedItemColor : _unselectedItemColor;

  Widget _buildIcon(IconData iconData,String text,int index) => Container(
    width: double.infinity,height: kBottomNavigationBarHeight,child: Material(
      color: _getBgColor(index),child: InkWell(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
            Icon(iconData),Text(text,style: TextStyle(fontSize: 9,color: _getItemColor(index))),],onTap: () => _onItemTapped(index),);

  _appBar(height) => PreferredSize(
    preferredSize:  Size(MediaQuery.of(context).size.width,height+80 ),child: Stack(
      children: <Widget>[
        Container(
          child: Center(
            child: Text("TEXT",style: TextStyle(fontSize: 15.0,fontWeight: FontWeight.w600,color: Colors.white),color:Theme.of(context).primaryColor,height: height+75,width: MediaQuery.of(context).size.width,Container(
        ),Positioned(    // To take AppBar Size only
          top: 100.0,left: 20.0,right: 20.0,child: AppBar(
            backgroundColor: Color(0xFF293749),leading: Icon(Icons.menu,primary: false,title: Container(
              margin: EdgeInsets.only(top: 4.0,bottom: 4.0,right: 0.0,left: 0.0),color: Colors.white,child: Container(
                margin: EdgeInsets.only(top: 0.0,bottom: 0.0,right: 5.0,left: 5.0),child: TextField(
                    decoration: Inputdecoration(
                        hintText: "Suchen",border: InputBorder.none,hintStyle: TextStyle(color: Colors.grey))),actions: <Widget>[
              IconButton(
                icon: Icon(Icons.search,onpressed: () {},)
      ],);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _appBar(AppBar().preferredSize.height),body: Center(
        child: _widgetoptions.elementAt(_selectedindex),bottomNavigationBar: BottomNavigationBar(
        selectedFontSize: 0,items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: _buildIcon(Icons.arrow_back_ios_rounded,'ZURÜCK',0),title: SizedBox.shrink(),BottomNavigationBarItem(
            icon: _buildIcon(Icons.favorite,'FAVORITEN',1),BottomNavigationBarItem(
            icon: _buildIcon(Icons.comment,'KOMMENTARE',2),BottomNavigationBarItem(
            icon: _buildIcon(Icons.info_outline_rounded,'ÜBER UNS',3),BottomNavigationBarItem(
            icon: _buildIcon(Icons.arrow_forward_ios_rounded,'WEITER',4),currentIndex: _selectedindex,selectedItemColor: _selectedItemColor,unselectedItemColor: _unselectedItemColor,);
  }
}

解决方法

我已经用一些注释修改了您的代码,以支持您构建 UI。

对于 AppBar,您正朝着正确的方向使用 PreferredSizeStack,只是进行了一些细微的调整。

对于 BottomNavigationBar,由于提供的 BottomNavigationBarItem 已经具有 icontitle 属性,我们可以使用它并修改其父级的颜色。 2 个箭头按钮可以放在 Row 中。

完整示例如下:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      themeMode: ThemeMode.light,theme: ThemeData(
          primaryColor: Color(0xFF34445c),primaryColorBrightness: Brightness.light,brightness: Brightness.light,primaryColorDark: Colors.black,canvasColor: Color(0xFFCECECE),appBarTheme: AppBarTheme(brightness: Brightness.light)),darkTheme: ThemeData(
          primaryColor: Colors.black,primaryColorBrightness: Brightness.dark,primaryColorLight: Colors.black,brightness: Brightness.dark,indicatorColor: Colors.white,canvasColor: Colors.black,appBarTheme: AppBarTheme(brightness: Brightness.dark)),home: MyHomePage(),);
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key,this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _selectedItemColor = Colors.white;
  final _unselectedItemColor = Colors.white30;
  final _selectedBgColor = Color(0xFF293749);
  final _unselectedBgColor = Color(0xFF34445c);
  int _selectedIndex = 0;
  static const TextStyle optionStyle =
      TextStyle(fontSize: 15,fontWeight: FontWeight.normal);

  static const List<Widget> _widgetOptions = <Widget>[
    Text(
      'Index 0: ZURÜCK',style: optionStyle,),Text(
      'Index 1: FAVORITES',Text(
      'Index 2: KOMMENTARE / LÖSCHEN',Text(
      'Index 3: ABOUT-US',Text(
      'Index 4: WEITER',];

  _appBar() => PreferredSize(
        preferredSize: Size.fromHeight(300),child: Container(
          height: 300,child: Stack(
            children: <Widget>[
              Container(
                color: Color(0xFF34445D),height: 180,child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,children: [
                    Text(
                      "APP TITLE",style: TextStyle(
                          fontSize: 20.0,fontWeight: FontWeight.w600,color: Colors.white),SizedBox(height: 20),Row(
                      mainAxisAlignment: MainAxisAlignment.center,children: List<Widget>.generate(
                        4,(index) => Padding(
                          padding: EdgeInsets.symmetric(horizontal: 8.0),child: Icon(Icons.people,// Sample icons for demonstration
                        ),)
                  ],Positioned(
                top: 150.0,left: 20.0,right: 20.0,child: Container(
                  color: Color(0xFF293749),child: Row(
                    children: [
                      IconButton(
                        icon: Icon(Icons.menu,size: 40,padding: EdgeInsets.zero,onPressed: () {},Expanded(
                        child: Container(
                          margin: EdgeInsets.symmetric(vertical: 3),padding: EdgeInsets.only(left: 3),color: Colors.white,height: 30,child: TextField(
                            style: TextStyle(color: Colors.black,fontSize: 12),decoration: InputDecoration(
                                hintText: 'Search...',border: InputBorder.none),IconButton(
                        icon: Icon(Icons.search,size: 30,],);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _appBar(),body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),bottomNavigationBar: Container(
        color: _selectedBgColor,child: Row(
          children: [
            IconButton(
              icon: Icon(Icons.arrow_back_ios,onPressed: () {
                setState(() {
                  _selectedIndex =
                      _selectedIndex <= 0 ? _selectedIndex : _selectedIndex - 1;
                });
              },Expanded(
              child: BottomNavigationBar(
                type: BottomNavigationBarType.fixed,// Add the type here to avoid auto resize
                backgroundColor: _selectedBgColor,// You can also set the unselectedBackgroundColor
                currentIndex: _selectedIndex,onTap: (index) => setState(() => _selectedIndex = index),// Update the selected index
                selectedItemColor: _selectedItemColor,unselectedItemColor: _unselectedItemColor,items: <BottomNavigationBarItem>[
                  BottomNavigationBarItem(
                      icon: Icon(Icons.favorite),title: Text('FAVORITEN')),BottomNavigationBarItem(
                      icon: Icon(Icons.comment),title: Text('KOMMENTARE')),BottomNavigationBarItem(
                      icon: Icon(Icons.info_outline_rounded),title: Text('ÜBER UNS')),IconButton(
              icon: Icon(Icons.arrow_forward_ios,onPressed: () {
                setState(() {
                  _selectedIndex =
                      _selectedIndex >= 2 ? _selectedIndex : _selectedIndex + 1;
                });
              },);
  }
}