質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

ボトムナビゲーションバーに画像を使用した際、読み込み中に何も表示されない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 573

score 18

前提・実現したいこと

Flutterを使用したスマホアプリを作っています。
ボトムナビゲーションバーでオリジナルの画像を使用しています。
現状表示はできているのですが、画像を使用した際、読み込み中の2〜3秒間、何も表示されないのですが、何かいい方法ありましたら教えてもらいたいです。
現状のコードではニュースページのみ、非同期処理を行って、通知の有無で場合わけしています。

発生している問題・エラーメッセージ

特になし

該当のソースコード

以下、main.dart

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

import 'custom_bottom_navigation_bar.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  SystemChrome.setPreferredOrientations([
  ]);
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: RootPage(),
    );
  }
}

class RootPage extends StatefulWidget {
  @override
  _RootPageState createState() => _RootPageState();
}

class _RootPageState extends State<RootPage> {
  int _selectedIndex = 0;
  PageController _pageController;

  static List<Widget> _pageList = [
    SimplePage(text: 'ホーム'),
    SimplePage(text: 'ニュース'),
    SimplePage(text: '検索'),
    SimplePage(text: 'その他'),
  ];

  void _onPageChanged(int index){
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  void initState() {
    _pageController = PageController(
      initialPage: _selectedIndex,
    );
    super.initState();
  }

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text("SampleApp"),
      ),
      body: _pageList.elementAt(_selectedIndex),
      bottomNavigationBar: CustomBottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
    );

  }

  void _onItemTapped(int index) => setState(() => _selectedIndex = index);
}

class SimplePage extends StatelessWidget {
  final String text;
  SimplePage({this.text});
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(text),
    );
  }
}

以下、custom_bottom_navigation_bar.dart

import 'package:flutter/material.dart';

class CustomBottomNavigationBar extends BottomNavigationBar {
  CustomBottomNavigationBar({int currentIndex, ValueChanged<int> onTap})
    : super (
      items: <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: (currentIndex == 0)
            ? Image.asset("images/icon/home_on.png")
            : Image.asset("images/icon/home_off.png"),
          label: 'ホーム', 
        ),
        BottomNavigationBarItem(
          icon: (currentIndex == 1)
            ? Image.asset("images/icon/news_on.png")
            : NewsOffIcon(),
          label: 'ホーム', 
        ),
        BottomNavigationBarItem(
          icon: (currentIndex == 2)
            ? Image.asset("images/icon/serch_on.png")
            : Image.asset("images/icon/serch_off.png"),
          label: 'ホーム', 
        ),
        BottomNavigationBarItem(
          icon: (currentIndex == 3)
            ? Image.asset("images/icon/other_on.png")
            : Image.asset("images/icon/other_off.png"),
          label: 'ホーム', 
        ),
      ],
      currentIndex: currentIndex,
      onTap: onTap,
      selectedItemColor: Colors.red,
      unselectedItemColor: Colors.grey,
      type: BottomNavigationBarType.fixed,
    );
}

class NewsOffIcon extends StatefulWidget {
  @override
  _NewsOffIconState createState() => _NewsOffIconState();
}

class _NewsOffIconState extends State<NewsOffIcon> {
  Future<bool> _future;
  bool hasNew = false;

  @override
  void initState() {
    _future = _hasNewInfo();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _future,
      builder: (context, snapshot) {
        if(snapshot.hasData){
          if(hasNew){
            //通知がある場合の画像
          return Image.asset("images/icon/news_off_new.png");
          }
        }
        //通知がない場合の画像
        return Image.asset("images/icon/news_off.png");
      }
    );
  }

  Future<bool> _hasNewInfo() async {
    //非同期処理
    //新着通知がある場合、hasNew = trueの処理
  }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

確かにアセットからの読み込み遅いですよねFlutter。
precacheImage関数であらかじめロードしておくことはできます。
https://api.flutter.dev/flutter/widgets/precacheImage.html
使うタイミングが重要なのでよく考えてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/02/20 23:53

    いつもありがとうございます!
    precacheImage知らなかったので調べて使ってみようかと思います!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る