2017-10-18 9 views
0

私はFlutterを学んでおり、Widgetを組み込みのCircleAvatarと同じようにしたいと考えています。しかし、私は羽ばたき:吹き返しのテキストを含むCircleAvatar

  • は(NetworkImage)の両方の画像を指定し、イメージがロードされていない状態の画像がない場合はイニシャル(すなわち、BB)
  • 、イニシャル
  • を表示する行動をしたいと思います読み込み、画像の表示、イニシャルの削除

次のコードは動作しますが、チャットのデモで使用すると、複数のMyAvatarsが追加されているため、離れてしまいます。 initStateのブレークポイントは、最初に入力したメッセージテキストで常に呼び出されることを示しています。 イメージ "リロード"としてもちらつきます。ウィジェットは私が理解できない方法で再利用されているようです。私はまだ問題を抱えている

class MyAvatar extends StatefulWidget {      
    NetworkImage image; 
    MyAvatar({this.text}) { 
    debugPrint("MyAvatar " + this.text); 
    if (text.contains('fun')) { 
     this.image = new NetworkImage("https://cdn3.iconfinder.com/data/icons/minicons-for-web-sites/24/minicons2-14-512.png"); 
    } 
    } 
    final String text; 
    @override               
    MyAvatarState createState() { 
    return new MyAvatarState(); 
    }      
} 

class MyAvatarState extends State<MyAvatar> { 
    bool showImage = false; 
    @override 
    initState() { 
    super.initState(); 
    if (widget.image != null) { 
     var completer = widget.image.load(widget.image); 
     completer.addListener((info, sync) { 
     setState(() { 
      showImage = true; 
     }); 
     }); 
    } 
    } 

    @override 
    Widget build(BuildContext context) { 
    return !showImage ? new CircleAvatar(radius: 40.0, child: new Text(widget.text[0])) 
     : new CircleAvatar(radius: 40.0, backgroundImage: widget.image); 
    } 
} 

- 完全なコード

import 'package:flutter/material.dart'; 
// Modify the ChatScreen class definition to extend StatefulWidget. 

class ChatScreen extends StatefulWidget {      //modified 
    ChatScreen() { 
    debugPrint("ChatScreen - called on hot reload"); 
    } 
    @override              //new 
    State createState() { 
    debugPrint("NOT on hot reload"); 
    return new ChatScreenState(); 
    }     //new 
} 

// Add the ChatScreenState class definition in main.dart. 

class ChatScreenState extends State<ChatScreen> { 
    final List<ChatMessage> _messages = <ChatMessage>[]; 
    final TextEditingController _textController = new TextEditingController(); //new 
    ChatScreenState() { 
    debugPrint("ChatScreenState - not called on hot reload"); 
    } 

    @override //new 
    Widget build(BuildContext context) { 
    return new Scaffold(
     appBar: new AppBar(title: new Text("Friendlychat")), 
     body: new Column(          //modified 
      children: <Widget>[           //new 
      new Flexible(            //new 
       child: new ListView.builder(        //new 
        padding: new EdgeInsets.all(8.0),      //new 
        reverse: true,           //new 
        itemBuilder: (_, int index) => _messages[index],  //new 
        itemCount: _messages.length,       //new 
       )               //new 
      ),               //new 
      new Divider(height: 1.0),         //new 
      new Container(            //new 
       decoration: new BoxDecoration(
        color: Theme.of(context).cardColor),     //new 
       child: _buildTextComposer(),       //modified 
      ),               //new 
      ]               //new 
    ),                //new 
    ); 
    } 

    Widget _buildTextComposer() { 

    return new IconTheme(
     data: new IconThemeData(color: Theme 
      .of(context) 
      .accentColor), 
     child: 
     new Container(
      margin: const EdgeInsets.symmetric(horizontal: 8.0), 
      child: new Row(
       children: <Widget>[ 
        new Container(//new 
        margin: new EdgeInsets.symmetric(horizontal: 4.0), //new 
        child: new IconButton(//new 
         icon: new Icon(Icons.send), 
         onPressed:() => 
          _handleSubmitted(_textController.text)), //new 
       ), 
        new Flexible(
         child: new TextField(
         controller: _textController, 
         onSubmitted: _handleSubmitted, 
         decoration: new InputDecoration.collapsed(
          hintText: "Send a message"), 
        ) 
       ), 
       ]) 
     ) 
    ); 
    } 

    void _handleSubmitted(String text) { 


    _textController.clear(); 
    ChatMessage message = new ChatMessage(text: text); 
    setState(() { 
     _messages.insert(0, message); 
    }); 
    } 
} 

const String _name = "Hardcoded Name"; 

class ChatMessage extends StatelessWidget { 
    ChatMessage({this.text, this.image, this.useImage}); 
    final String text; 
    final NetworkImage image; 
    final Map useImage; 
    @override 
    Widget build(BuildContext context) { 
    var use = true; //useImage != null && useImage['use']; 

    var image = new NetworkImage("https://cdn3.iconfinder.com/data/icons/minicons-for-web-sites/24/minicons2-14-512.png"); 
    if (text.contains('bad')) { 
     image = new NetworkImage("https://cdn3.iconfinder.com/data/icons/minicons-for-web-sites/24/minicons2-14-512.pngz"); 
    } 
    return new Container(
     margin: const EdgeInsets.symmetric(vertical: 10.0), 
     child: new Row(
     crossAxisAlignment: CrossAxisAlignment.start, 
     children: <Widget>[ 
      new Container(
      margin: const EdgeInsets.only(right: 16.0), 
      child : new CustomCircleAvatar(initials: text[0], myImage: image) 
     ), 
      new Column(
      crossAxisAlignment: CrossAxisAlignment.start, 
      children: <Widget>[ 
       new Text(_name, style: Theme.of(context).textTheme.subhead), 
       new Container(
       margin: const EdgeInsets.only(top: 5.0), 
       child: new Text(text), 
      ), 
      ], 
     ), 
     ], 
    ), 
    ); 
    } 
} 

class CustomCircleAvatar extends StatefulWidget { 
    NetworkImage myImage; 

    String initials; 


    CustomCircleAvatar({this.myImage, this.initials}) { 
    debugPrint(initials); 
    } 

    @override 
    _CustomCircleAvatarState createState() => new _CustomCircleAvatarState(); 
} 

class _CustomCircleAvatarState extends State<CustomCircleAvatar>{ 

    bool _checkLoading = true; 

    @override 
    void initState() { 
    if (widget.myImage != null) { 
     widget.myImage.resolve(new ImageConfiguration()).addListener((image, sync) { 
     if (mounted && image != null) { 
      setState(() { 
      _checkLoading = false; 
      }); 
     } 
     }); 
    } 
    } 

    @override 
    Widget build(BuildContext context) { 
    return _checkLoading == true ? new CircleAvatar(child: new Text(widget.initials)) 
     : new CircleAvatar(backgroundImage: widget.myImage); 
    } 
} 

秒などし、「悪い」というメッセージとして「楽しい」と入力 - アイデアは何に依存していることである image 異なる画像が読み込まれる可能性があります。 「読み込みに失敗しました」ケースでは、イニシャルをそのまま残す必要があります。ここで

あなたは ImageConfigurationから入手することができます ImageStreamにリスナーを追加することによって、この機能を実現することができます

答えて

1

、私は同じデータを供給しています私のListViewあなたはもちろん、画像のListを追加することによって、この自分でカスタマイズすることができますおよびイニシャルを任意のクラスのフィールドとして使用し、代わりにListView.builderを使用してインデックスでループすることができます。

enter image description here

class CustomCircleAvatar extends StatefulWidget { 
    NetworkImage myImage; 

    String initials; 


    CustomCircleAvatar({this.myImage, this.initials}); 

    @override 
    _CustomCircleAvatarState createState() => new _CustomCircleAvatarState(); 
} 

class _CustomCircleAvatarState extends State<CustomCircleAvatar>{ 

    bool _checkLoading = true; 

    @override 
    void initState() { 
    widget.myImage.resolve(new ImageConfiguration()).addListener((_, __) { 
     if (mounted) { 
     setState(() { 
      _checkLoading = false; 
     }); 
     } 
    }); 
    } 

    @override 
    Widget build(BuildContext context) { 
    return _checkLoading == true ? new CircleAvatar(
     child: new Text(widget.initials)) : new CircleAvatar(
     backgroundImage: widget.myImage,); 
    } 
} 

は今、あなたはこのようにそれを使用することができます:

void main() { 
    runApp(new MaterialApp (home: new MyApp())); 
} 

    class MyApp extends StatefulWidget { 
     @override 
     _MyAppState createState() => new _MyAppState(); 
    } 

    class _MyAppState extends State<MyApp> { 
     @override 
     Widget build(BuildContext context) { 
     return new Scaffold(
      appBar: new AppBar(title: new Text("Custom Circle Avatar"),), 
      body: new ListView(children: new List.generate(20, (int index) { 
      return new Container(
       height: 100.0, 
       width: 100.0, 
       child: new CustomCircleAvatar(myImage: new NetworkImage(
        "https://www.doginni.cz/front_path/images/dog_circle.png"), 
       initials: "Dog", 
      ), 
      ); 
      }),), 
     ); 
     } 
    } 
+0

優秀だこと - それは完全に働いた、どうもありがとうございました。今なぜ理解するのですか: – bradbeveridge

+0

@bradbeveridge私は助けてくれてうれしいです、あなたは私にあなたが得ているエラーを再現できるものを与えることができます – aziza

+0

私は間違っていました、私はまだ私が私は元の質問を更新しました。あなたの時間と助けをありがとう、ありがとう。 – bradbeveridge

関連する問題