Как решить эту проблему, когда Flutter MaterialPageRoute перемещается на экран с черным фоном? - PullRequest
2 голосов
/ 14 января 2020

Я впервые использую Flutter для одного из моих проектов, который является газетным приложением.

Проблема возникает, когда я пытаюсь перейти от main.dart к newsfeed_for_other_category.dart, используя MaterialPageRoute от моего Drawer. На этом экране отображаются новости, но на черном фоне. Но на экране newsfeed_screen.dart, который вызывается в теле в моем main.dart, он показывает отлично.

Я выкладываю коды ниже.

main.dart

import 'package:flutter/material.dart';
import './SizeConfig.dart';
import './screens/newsfeed_screen.dart';
import 'package:curved_navigation_bar/curved_navigation_bar.dart';
import 'factory/widget_factory.dart';
import 'widgets/top_news_widget.dart';
import 'package:splashscreen/splashscreen.dart';
import './widgets/drawer.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Newspaper App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        //backgroundColor: Colors.lightGreenAccent,
      ),
      home: MyHomePage(title: 'The Business Standard'),
      routes: <String, WidgetBuilder> {
        '/screen1': (BuildContext context) => new NewsFeedScreen(216, 5, "Top News"),
        '/screen2' : (BuildContext context) => new NewsFeedScreen(4, 7, "National"),
        '/screen3' : (BuildContext context) => new NewsFeedScreen(13, 70, "International"),
        /*'/screen4' : (BuildContext context) => new Screen4()*/
      },
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: '_MainScreenKey');

  Widget build(BuildContext context) {
    return SplashScreen(
        seconds: 3,
        navigateAfterSeconds: AfterSplash(),
        title: Text(
          'The Business Standard',
          style: TextStyle(
              fontWeight: FontWeight.bold,
              fontSize: 20.0
          ),
        ),
        image: Image.asset(
            'assets/TBS_logo.jpg',
        ),
        backgroundColor: Colors.white,
        styleTextUnderTheLoader: TextStyle(),
        photoSize: 100.0,
        onClick: ()=>print("Flutter Egypt"),
        loaderColor: Colors.red
    );
  }
}

class AfterSplash extends StatefulWidget {

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

class _AfterSplashState extends State<AfterSplash> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: '_MainScreenKey');

  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        backgroundColor: Colors.white,
        title: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            Image.asset(
              'assets/TBS.png',
              fit: BoxFit.cover,
              height: 45,
            )
          ],
        ),
        leading: IconButton(
          icon: Icon(Icons.dehaze),
          color: Colors.black,
          onPressed: () => _scaffoldKey.currentState.openDrawer(),
        ),
      ),
      drawer: SideDrawer(),
      body: NewsFeedScreen(22, 71, "Sports"),
      bottomNavigationBar: CurvedNavigationBar(
        backgroundColor: const Color(0xFF2b4849),
        items: <Widget>[
          Icon(Icons.bookmark, size: 30,),
          Icon(Icons.perm_identity, size: 30,),
          Icon(Icons.settings, size: 30,),
        ],
        onTap: (index) {
          if(index == 2) {
            _scaffoldKey.currentState.showSnackBar(const SnackBar(
                content: const Text('Will open Settings menu')));
          } else if(index == 0) {
            _scaffoldKey.currentState.showSnackBar(const SnackBar(
                content: const Text('Implement Bookmark function')));
          } else {
            _scaffoldKey.currentState.showSnackBar(const SnackBar(
                content: const Text('Will show User profile and information')));
          }
        },
      ),
    );
  }
}

newsfeed_for_other_category.dart - страница, на которую я перехожу, и здесь отображается черный фон.

import 'package:flutter/material.dart';
import '../SizeConfig.dart';
import '../widgets/headlines.dart';
import '../widgets/secondary_headlines.dart';
import '../widgets/listed_news.dart';
import '../models/NewsPost.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:developer';
import '../screens/newsPost_details.dart';
import '../screens/newsfeed_for_specific_category.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import '../transition_animation_routes/ScaleTransitionRoute.dart';
import '../widgets/top_news_widget.dart';

class NewsfeedForOtherCategory extends StatefulWidget {
  int categoryId;
  int childrenCategoryId;
  String categoryName;

  NewsfeedForOtherCategory(this.categoryId, this.childrenCategoryId, this.categoryName);
  @override
  _NewsfeedForOtherCategoryState createState() => _NewsfeedForOtherCategoryState(this.categoryId, this.childrenCategoryId, this.categoryName);
}

class _NewsfeedForOtherCategoryState extends State<NewsfeedForOtherCategory> {
  int categoryId;
  int childrenCategoryId;
  String categoryName;

  _NewsfeedForOtherCategoryState(this.categoryId, this.childrenCategoryId, this.categoryName);

  bool _isRequestSent = false;
  List<NewsPost> newsPostList = [];

  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);

    if(!_isRequestSent) {
      _sendRequest();
    }

    return Container(
      alignment: Alignment.center,
      child: !_isRequestSent
          ? CircularProgressIndicator()
          : Container(
        child: ListView.builder(
            itemCount: newsPostList.length,
            scrollDirection: Axis.vertical,
            itemBuilder: (BuildContext context, int index) {
              return _getNewsPostWidgets(index);
            }
        ),
      ),
    );
  }

  void _sendRequest() async {
    String url = "https://tbsnews.net/json/category/news/"+this.categoryId.toString()+"/"+this.childrenCategoryId.toString()+"";
    http.Response response = await http.get(url);
    List<dynamic> decode = json.decode(response.body);
    log('response: $response');
    List results = decode[0]['items'];
    for (var jsonObject in results) {
      var post = NewsPost.getNewsPostFromAPI(jsonObject);
      newsPostList.add(post);
      print(post);
    }
    setState(() => _isRequestSent = true);
  }

  Widget _getNewsPostWidgets(int index) {
    var newsPost = newsPostList[index];

    if(index < this.newsPostList.length) {
      if(index == 0) {
        return GestureDetector(
            onTap: () {
              Navigator.push(
                  context,
                  ScaleTransitionRoute(
                      page: NewsPostDetails(newsPostList, index)
                  )
              );
            },
            child: Column(
              children: <Widget>[
                Container(
                  padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
                  //constraints: BoxConstraints(minWidth: double.infinity, maxWidth: double.infinity),
                  constraints: BoxConstraints.expand(
                      width: double.infinity,
                      height: 40
                  ),
                  color: const Color(0xFF2b4849),
                  child: Text(
                    this.categoryName,
                    style: TextStyle(
                        fontSize: 33,
                        color: Colors.white
                    ),
                  ),
                ),
                BlockHeadline(newsPost)
              ],
            )
        );
      }
      else {
        return GestureDetector(
          onTap: () {
            Navigator.push(
                context,
                ScaleTransitionRoute(
                    page: NewsPostDetails(newsPostList, index)
                )
            );
          },
          child: ListedNews(newsPost),
        );
      }
    }
    else {
      return Container(
        color: const Color(0xFF2b4849),
        child: index == 3 ? FlatButton(
          child: Text(
            "Load More",
            style: TextStyle(
                color: Colors.white
            ),
          ),
          onPressed: () {
            Navigator.push(
                context,
                MaterialPageRoute(
                    builder: (BuildContext context) => NewsFeedForSpecificCategory(newsPostList)
                )
            );
          },
        ) : Container(),
      );
    }
  }

  openNewsPostDetails(List<NewsPost> newsPostList, int index) {
    Navigator.push(
        context,
        ScaleTransitionRoute(
            page: NewsPostDetails(newsPostList, index)
        )
    );
  }
}

хоть и переворачивается * :ол.dart

import 'package:flutter/material.dart';
import '../SizeConfig.dart';
import '../screens/newsfeed_for_other_category.dart';

class SideDrawer extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return SizedBox(
      width: SizeConfig.safeBlockHorizontal*50,
      child: Theme(
        data: Theme.of(context).copyWith(canvasColor: const Color(0xFF2b4849)),
        child: Drawer(
          child: ListView(
            children: <Widget>[
              ListTile(
                title: Text(
                  'Top News',
                  style: TextStyle(
                      fontSize: 20,
                      color: Colors.white
                  ),
                ),
                onTap: () {
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (BuildContext context) => NewsfeedForOtherCategory(216, 5, "Top News")
                      )
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

На моем домашнем экране, который newsfeed_screen.dart вызывается в теле AfterSplashState виджета в main.dart, он выглядит так, как показано ниже.

enter image description here

Но на экране NewsfeedForOtherCategory, к которому я перемещаюсь с помощью drawer, выглядит ниже с черным фоном.

enter image description here

Я пытался использовать Navigator.of(context, rootNavigator: true).pushNamed('/route') и pushReplacementNamed() также вместо MaterialPageRoute. Но бесполезно.

Вот связанный вопрос , который я нашел, я попробовал решения, которые они дали, но у меня не сработало.

Также упомянуть, На странице, на которую я перехожу, нет виджета MaterialApp, только у main.dart. Так что не должно быть проблемы.

Я использую машину с Ubuntu 16.04.

Некоторые подсказки от вас будут бесценны. Большое спасибо за ваше время.

Ответы [ 3 ]

2 голосов
/ 14 января 2020
Страница

NewsfeedForOtherCategory черная, потому что в ней нет контейнера Material. Вы можете просто обернуть его с помощью Material виджета или Scaffold (который имеет некоторые дополнительные функции, такие как ящик, плавающая кнопка действия).

И из вашего скриншота я вижу, что некоторые виджеты переполнены панелью уведомлений. Вы можете использовать SafeArea внутри Material или внутри body из Scaffold, чтобы преодолеть это.

2 голосов
/ 14 января 2020

Оберните основной контейнер в NewsfeedForOtherCategory леской, и у вас есть решение.

    ...
    return Scaffold(
      body: Container(
          alignment: Alignment.center,
          child: !_isRequestSent
              ? CircularProgressIndicator()
              : Container(
            child: ListView.builder(
                itemCount: newsPostList.length,
                scrollDirection: Axis.vertical,
                itemBuilder: (BuildContext context, int index) {
                  return _getNewsPostWidgets(index);
                }
            ),
          ),
        );
    );
    ...
0 голосов
/ 14 января 2020

В функции сборки вашего виджета NewsfeedForOtherCategory попробуйте поместить то, что у вас есть, в Scaffold. Нравится:

    return Scaffold(
              body: Container(
                alignment: Alignment.center,
                child: !_isRequestSent
                    ? CircularProgressIndicator()
                    : Container(
                        child: ListView.builder(
                            itemCount: newsPostList.length,
                            scrollDirection: Axis.vertical,
                            itemBuilder: (BuildContext context, int index) {
                              return _getNewsPostWidgets(index);
                            }),
                      ),
              ),
            ),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...