2017-10-18 1 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

,

, I가 동일한 데이터를 공급하고 내 ListView 당신은 물론 이미지의 List를 추가하여이 자신을 사용자 정의 할 수 있습니다 이니셜을 모든 클래스의 필드로 사용하고 ListView.builder을 대신 사용하여 인덱스로 루프 할 수 있습니다.

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,); 
    } 
} 

enter image description here

이제 다음과 같이 사용할 수 있습니다 : 우수의

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

관련 문제