Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 7

13
votes
answers
20 views
+10

Flutter:如何修复ITMS-90809:不推荐使用的API使用 - Apple将停止接受使用UIWebView API的应用程序的提交

在提交我的最新版本时,Apple突然返回一条消息,说明存在问题,具体为:

ITMS-90809:不推荐使用的API使用情况 - Apple将停止接受使用的应用提交UIWebView API。有关详细信息,请参见 https://developer.apple.com/documentation/uikit/uiwebview

由于我没有使用webview插件,我对使用 UIWebView API 的地方感到很遗憾。有关如何解决此问题的任何建议吗?

此错误出现在最新的稳定颤振版本1.7.8 + hotfix.4中,并包含以下软件包:

  http: ^ 0.12。0 [?] Android工具链 - 针对Android设备开发(Android SDK版本28.0.3)?Android SDK位于/ Users / per / Library / Android / sdk?Android NDK位置未配置(可选;对原生分析支持很有用)?平台android-28,build-tools 28.0.3?Java二进制文件:/ Applications / AndroidStudio.app/Contents/jre/jdk/Contents/Home/bin/java?JavaScriptOpenJDK Runtime Environment(build 1.8.0_152- release- 1136-b06)?接受所有Android许可。[?] Xcode  - 针对iOS和macOS开发(Xcode 10.3)?Xcode位于/Applications/Xcode.app/Contents/Developer?Xcode 10.3,Build版本10G8?CocoaPods版本1.7.4 [?] iOS工具 - 针对iOS设备开发?ios-deploy 1.9.4 [?] Android Studio(版本3.2)?Android Studio at / Applications / Android Studio.app/Contents?Flutter插件版本31。3.1?Dart插件版本181.5656?Java版OpenJDK运行时环境(版本1.8.0_152-release-1136-b06)[?] VS代码(版本1.31.1)?VS代码/ Applications / Visual Studio Code.app/Contents? Flutter扩展版本2.25.1 [?]连接设备(1个可用)?Nexus 6P?5VT7N15C31001152?android-arm64?Android 8.1.0(API 27)?未发现任何问题! 
    
        
沙发
+90
+50

我认为它是从firebase_auth插件中使用的。尝试将其更新为最新版本,然后记住运行 pod update

我倾向于同意这一点,因为搜索包含UIWebView引用的唯一数据包。我现在已经更新到firebase_auth的最新版本,并且无法再找到任何对UIWebView的引用。 - 本8月29日17:07

颤抖的团队似乎意识到了。github.com/firebase/firebase-ios-sdk/pull/3723 - 本8月29日17:14

更新到firebase_auth 0.14.0 + 5并更新pod后,对UIWebView的引用似乎消失了。希望这意味着提交不会再顺利进行。 - Paul-Erik Raue 8月30日凌晨4点28分

这是唯一对我有用的答案。 - Sheshank S. 8月30日22:13

+40

我使用我们的Cordova应用程序并通过更新依赖项修复它。

您是否有机会使用依赖项或其他依赖项使用依赖项“cordova-plugin-inappbrowser”。< / p>

如果是这样,这应该在3.1.0中修复。请参阅发布说明 https://github.com/apache/ cordova-plugin-inappbrowser / blob / master / RELEASENOTES.md 和PR修复它 https://github.com/apache/cordova-plugin-inappbrowser/pull/271

更新:它还没有修复。请参阅cordova-ios上的问题:<

嗯,即使我从Cordova应用程序中删除所有插件,我也会收到相同的电子邮件。 - Tonald Drump 8月29日10:26

是的,我可以确认我还在接受它们。所以它在科尔多瓦也必须是其他东西。Ionic webview也有这个问题:github.com/ionic-team/cordova-plugin-ionic-webview/issues/428 - Klaasvaak 8月29日12:23

另见github.com/apache/cordova-ios/issues/661 - Klaasvaak 8月29日12:26

谢谢(你的)信息。我没有使用Cordova,所以这不是原因,但firebase软件包似乎导致了这一点。 - Paul-Erik Raue 8月30日凌晨4点23分

0
votes
answers
51 views
+10

Flutter應用程序中顯示圖像和用戶反應的準確時間

1

我必須創建一個心理反應時間測試應用程序。爲此,我必須準確地控制圖像何時可見,並準確測量圖像可見性開始和反應開始(例如點擊事件)之間的延遲。 我該如何在Flutter中實現?具體而言,在同一地點顯示和隱藏多個不同圖像的最有效方式是什麼?我如何才能準確知道點擊事件的發生與真實和完全可見性的發生相關,並考慮到幀設備的速率?是否有辦法對這個過程進行低級控制。通常Flutter似乎暴露了高級別的API。Flutter應用程序中顯示圖像和用戶反應的準確時間

沙发
0
3

我已經做出了嘗試是有可能正是你在找什麼,我的邏輯如下:

  1. 添加監聽到的圖像呈現。
  2. 使用Stopwatch類,我通知我的對象在圖像顯示後開始計時。
  3. 當點擊正確答案時,我停止Stopwatch停止計數。
  4. 保存我目前的分數,並繼續下一個問題。

注:

  • 在這個例子中,爲簡單起見,我沒有爲哪個答案是正確的,這是不是一個帳戶。
  • 我創建了一個新的StatelessWidget來保存每個問題,使用PageView.builder也可能是一個很好的用法。

簡單的例子:

enter image description here

import 'dart:async'; 

import 'package:flutter/material.dart'; 

int score = 0; 

class TimeTest extends StatefulWidget { 
    Widget nextQuestionWidget; //to navigate 
    String question; 
    NetworkImage questionImage; 
    List<String> answers; 

    TimeTest(
     {this.questionImage, this.question, this.answers, this.nextQuestionWidget }); 

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

class _TimeTestState extends State<TimeTest> { 
    final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); 
    bool _loading = true; 
    Stopwatch timer = new Stopwatch(); 

    @override 
    void initState() { 
    widget.questionImage.resolve(new ImageConfiguration()).addListener((_, __) { 
     if (mounted) { 
     setState(() { 
      _loading = false; 
     }); 
     timer.start(); 
     } 
    }); 
    } 

    @override 
    Widget build(BuildContext context) { 
    return new Scaffold(
     key: _scaffoldKey, 
     appBar: new AppBar(title: new Text("Time Test"),), 
     body: new Container(
     alignment: FractionalOffset.center, 
     margin: const EdgeInsets.symmetric(vertical: 15.0), 
     child: new Column(
      children: <Widget>[ 
      new Text(widget.question), 
      new Divider(height: 15.0, color: Colors.blueAccent,), 
      new CircleAvatar(backgroundImage: widget.questionImage, 
       backgroundColor: Colors.transparent,), 
      new Container(height: 15.0,), 
      new Column(
       children: new List.generate(widget.answers.length, (int index) { 
       return new FlatButton(
        onPressed:() { 
        ///TODO 
        ///add conditions for correct or incorrect answers 
        ///and some manipulation on the score 
        timer.stop(); 
        score = score + timer.elapsedMilliseconds; 
        print(score); 
        _scaffoldKey.currentState.showSnackBar(new SnackBar(
         content: new Text(
          "Your answered this question in ${timer 
           .elapsedMilliseconds}ms"))); 

        ///Hold on before moving to the next question 
        new Future.delayed(const Duration(seconds: 3),() { 
         Navigator.of(context).push(new MaterialPageRoute(
          builder: (_) => widget.nextQuestionWidget)); 
        }); 
        }, child: new Text(widget.answers[index]),); 
       }), 
      ) 
      ], 

     ),), 
    ); 
    } 
} 


class QuestionOne extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new TimeTest(question: "Which animal is in this photo?", 
     questionImage: new NetworkImage(
      "http://cliparting.com/wp-content/uploads/2016/09/Tiger-free-to-use-clipart.png"), 
     answers: ["Lion", "Tiger", "Cheetah"], 
     nextQuestionWidget: new QuestionTwo(),); 
    } 
} 

class QuestionTwo extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new TimeTest(question: "Which bird is in this photo?", 
     questionImage: new NetworkImage(
      "http://www.clker.com/cliparts/P/q/7/9/j/q/eagle-hi.png"), 
     answers: ["Hawk", "Eagle", "Falcon"], 
     nextQuestionWidget: new ResultPage(),); 
    } 
} 

class ResultPage extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new Scaffold(
     appBar: new AppBar(title: new Text("Result"),), 
     body: new Center(
     child: new Text("CONGRATULATIONS! Your score is $score milliseconds"),), 
    ); 
    } 
} 
void main() { 
    runApp(new MaterialApp(home: new QuestionOne())); 
} 
+0

Grrrrrreat !!!!! – Michael

+0

此解決方案在屏幕上推送新路線。是不是像大量路線的內存泄漏?我寧願替換現有的圖像我如何存檔? – Michael

+0

我不想使用pushReplacement,因爲它取代了整個小部件。是否可以簡單地只交換圖像並在顯示時準確通知? – Michael

0
votes
answers
56 views
+10

我可以在Android上啓動聯繫人應用程序,並實際獲得選定的聯繫人手機號碼撲動?

0

有沒有辦法啓動聯繫人應用程序,並獲取任何撲翼應用程序後選擇的聯繫人號碼。我可以在Android上啓動聯繫人應用程序,並實際獲得選定的聯繫人手機號碼撲動?

我已經成功地只能使用urlurl_launcher包,但無法找到一個方法來返回選定聯繫人回到應用程序啓動,

請可有人告訴我,我們如何能在撲手機做到這一點應用。

非常感謝, 馬希

+0

請記住,如果您願意,可以進行android/IOS調用。 – Darky

沙发
0
1

這是不可能的url_launcher包。已有一個contact_picker package可用於撲動,允許您選擇一個聯繫人。

希望有幫助!

+0

謝謝@Hemanth Raj你是一個明星隊友,我會嘗試這個包,讓你知道如果這個作品非常感謝你。 – Mahi

+0

啊,沒關係!只要接受答案,如果它有幫助。 –

0
votes
answers
46 views
+10

顫動組列表與分隔符

1

我正在尋找一些指導來創建分隔符的列表視圖。例如,我想從按日期分組的數據庫中獲取消息,並按照日期將消息與某些圖形或行等分開,然後在分隔符下面顯示消息。試試這個撲動,任何指導或推動正確的方向將不勝感激。顫動組列表與分隔符

沙发
0
3

我的設計的醜陋道歉,但只是爲了告訴你,你幾乎可以建立自己的設計,你的願望,這是一個簡單的例子:

enter image description here

import "package:flutter/material.dart"; 
import 'package:meta/meta.dart'; 

class Test extends StatefulWidget { 
    @override 
    _TestState createState() => new _TestState(); 
} 

class _TestState extends State<Test> { 
    @override 
    Widget build(BuildContext context) { 
    return new Scaffold(
     appBar: new AppBar(
     title: new Text("Test"), 
    ), 
     body: new ListView.builder(
     // itemCount: myData.lenght(), 
      itemCount: 20, 
      itemBuilder: (BuildContext context, int index) { 
      //sort my data by timestamp before building 
      return new CustomWidget(date: "Convert my time stamp to date", 
       content: "My Awesome Content", 
       trailingIconOne: new Icon(Icons.share, color: Colors.blueAccent,), 
       trailingIconTwo: new Icon(
       Icons.favorite, color: Colors.redAccent,),); 
      }), 
    ); 
    } 
} 

class CustomWidget extends StatelessWidget { 
    String date; 
    String content; 

    Icon trailingIconOne; 

    Icon trailingIconTwo; 

    CustomWidget(
     {@required this.date, @required this.content, @required this.trailingIconOne, @required this.trailingIconTwo}); 

    @override 
    Widget build(BuildContext context) { 
    return new Container(
     decoration: new BoxDecoration(
      border: new Border.all(color: Colors.grey[500]) 
    ), 
     child: new Column(
     children: <Widget>[ 
      new Container (child: new Text(date), color: Colors.yellow[200],), 
      new Container(height: 15.0,), 
      new Text(content), 
      new Row(
      mainAxisAlignment: MainAxisAlignment.end, 
      children: <Widget>[ 
       new IconButton(icon: trailingIconOne, onPressed:() {}), 
       new Container(width: 10.0,), 
       new IconButton(icon: trailingIconTwo, onPressed:() {}) 
      ], 
     ) 
     ], 
    ), 
    ); 
    } 
} 

對於更好的設計,你可以擺脫邊框並使用Divider來代替:

return new Container(
     child: new Column(
     children: <Widget>[ 
      new Column (children: <Widget>[ 
      new Container (child: new Text(date), color: Colors.yellow[200],), 
      new Container(height: 15.0,), 
      new Text(content), 
      new Row(
       mainAxisAlignment: MainAxisAlignment.end, 
       children: <Widget>[ 
       new IconButton(icon: trailingIconOne, onPressed:() {}), 
       new Container(width: 10.0,), 
       new IconButton(icon: trailingIconTwo, onPressed:() {}), 
      ],), 

       new Divider(height: 15.0,color: Colors.red,), 
      ], 
     ) 
     ], 
    ), 

而且在我看來,更好的視覺解決方案是使用一個Card代替Container

return new Card(
     child: new Column(
     children: <Widget>[ 
      new Column (children: <Widget>[ 
      new Container (child: new Text(date), color: Colors.yellow[200],), 
      new Container(height: 15.0,), 
      new Text(content), 
      new Row(
       mainAxisAlignment: MainAxisAlignment.end, 
       children: <Widget>[ 
       new IconButton(icon: trailingIconOne, onPressed:() {}), 
       new Container(width: 10.0,), 
       new IconButton(icon: trailingIconTwo, onPressed:() {}), 
      ],), 

      // new Divider(height: 15.0,color: Colors.red,), 
      ], 
     ) 
     ], 
    ), 
    ); 
+1

謝謝,我認爲是足夠讓我從正確的方向開始。如果我一路卡住,我會發佈一個新項目。 – Robert

+0

不要那樣做!使用'new Divider()'而不是灰色邊框...... – Darky

+0

無論如何,我並不打算展示一個偉大的設計,是的Divider更好,但只是在這個特定的佈局中,它需要調整才能產生效果。我在最後添加了更改,如果我們使用Card而不是Container作爲父級,那麼這可能會是一個更好看的設計,但此示例僅用於表明您可以自定義自己的小部件。 – aziza

板凳
0
0

雖然這可能並不適用於您的情況,一個簡單的方法來分隔添加到ListView是使用ListView.divideTiles

// Adapted from https://flutter.io/flutter-for-android/#listviews--adapters 

import 'package:flutter/material.dart'; 

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

class MyApp extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new MaterialApp(
     title: 'Flutter Demo', 
     theme: new ThemeData(
     primarySwatch: Colors.blue, 
    ), 
     home: new ListExamplePage(), 
    ); 
    } 
} 

class ListExamplePage extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    // https://docs.flutter.io/flutter/material/ListTile/divideTiles.html 
    var dividedWidgetList = ListTile.divideTiles(
     context: context, 
     tiles: _getListData(), 
     color: Colors.black).toList(); 

    return new Scaffold(
     appBar: new AppBar(
     title: new Text('List Example'), 
    ), 
     body: new ListView(children: dividedWidgetList) 
    ); 
    } 

    _getListData() { 
    List<Widget> widgets = []; 
    for (int i=0; i<100; i++) { 
     widgets.add(
     new Padding(
      padding: new EdgeInsets.all(10.0), 
      child: new Text('Row $i')) 
    ); 
    } 
    return widgets; 
    } 
} 

編輯:

對於動態生成列表,ListTile.divideTiles不是正確的選擇。在其中列表項目建成階段添加分隔可能是最好的一段路要走:

import 'package:flutter/material.dart'; 

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

class MyApp extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new MaterialApp(
     title: 'Flutter Demo', 
     theme: new ThemeData(
     primarySwatch: Colors.blue, 
    ), 
     home: new ListExamplePage(), 
    ); 
    } 
} 

class ListExamplePage extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new Scaffold(
     appBar: new AppBar(
      title: new Text('List Example'), 
     ), 
     body: new ListView.builder(
      itemBuilder: (BuildContext context, int position) => 
       // Try using either _getRowWithDivider or _getRowWithBoxDecoration 
       // for two different ways of rendering a divider 
       _getRowWithDivider(position), 
     )); 
    } 

    /// Returns the widget at position i in the list, separated using a divider 
    Widget _getRowWithDivider(int i) { 
    var children = <Widget>[ 
     new Padding(padding: new EdgeInsets.all(10.0), child: new Text('Row $i')), 
     new Divider(height: 5.0), 
    ]; 

    return new Column(
     crossAxisAlignment: CrossAxisAlignment.start, 
     children: children, 
    ); 
    } 

// Returns the widget at position i in the list, separated using a BoxDecoration 
    Widget _getRowWithBoxDecoration(int i) { 
    return new Container(
     decoration: new BoxDecoration(
      border: 
       new Border(bottom: new BorderSide(color: Colors.grey[100]))), 
     child: new Padding(
      padding: new EdgeInsets.all(10.0), child: new Text('Row $i'))); 
    } 
} 
+0

這看起來很有希望,如果我通過http調用得到我的消息列表,那麼我將它放在一個列表中,現在我使用listview。生成器併爲每個項目應用一個小部件,但是現在我需要一個按日期分割的日期,每個日期可以是1或多個。我現在正在嘗試做一個列表視圖,其中包含消息列表視圖,但是與大小錯誤對等。您的解決方案看起來更直接,接受日期所需的分隔符而不是每個分隔符。任何建議都會很棒。 – Robert

+0

對於動態列表,不幸的是ListTile.divideTiles不會爲你工作。我建議使用aziza的建議,並在每行構建小部件時插入分隔符(或BoxDecoration)。我將更新一個不同的代碼片段來演示。 –

地板
0
0

簡單地把ListItemContainer,並添加裝飾:

@override 
    Widget build(BuildContext context) { 
    return new Container(
     child: new ListTile(
      title: new Text('I have border') 
     ), 
     decoration: 
      new BoxDecoration(
       border: new Border(
        bottom: new BorderSide() 
       ) 
      ) 
     ); 
    } 
66
votes
answers
39 views
+10

如何在Flutter中設置RaisedButton的寬度?

我已經看到我無法設置RaisedButtonFlutter中的a的寬度。如果我已經很好理解,我應該把它RaisedButton變成一個SizedBox。然後我將能夠設置盒子的寬度或高度。這是對的嗎?還有另一種方法嗎? SizedBox圍繞每個按鈕創建一個有點單調乏味,所以我想知道為什麼他們選擇這樣做。我很確定他們有充分的理由這樣做,但我沒有看到它。腳手架很難閱讀和為初學者建造。 new SizedBox( width: 200.0, height: 100.0, child: new RaisedButton( child: new Text('Blabla blablablablablablabla bla bla bla'), onPressed: _onButtonPressed, ), ),
up vote 37 down vote accepted favorite
沙发
+370
+50

As said in documentation here

Raised buttons have a minimum size of 88.0 by 36.0 which can be overidden with ButtonTheme.

You can do it like that

ButtonTheme(
  minWidth: 200.0,
  height: 100.0,
  child: RaisedButton(
    onPressed: () {},
    child: Texts.black("test"),
  ),
);

是否有類似“match_parent”的東西? - Pawan 11月12日,18:41

Hardcoding對我不起作用 - Pawan 11月12日18:41

+160

For match_parent you can use

SizedBox(
  width: double.infinity, // match_parent
  child: RaisedButton(...)
)

For any particular value you can use

SizedBox(
  width: 100, // specific value
  child: RaisedButton(...)
)

有趣的解決方案。我想我們應該使用邊距讓兩側有一些空的空間。 - OlivierGrenoble 1月17日8:44

在這種情況下,你應該使用Container而不是SizedBox - CopsOnRoad 3月15日10:21

+50

That's because flutter is not about size. It's about constraints.

Usually we have 2 use cases :

  • The child of a widget define a constraint. The parent size itself based on that information. ex : Padding, which takes the child constraint and increase it.
  • The parent enforce a constraint to it's child. ex : SizedBox, but also Column in strech mode, ...

RaisedButton is the first case. Which means it's the button which defines it's own height/width. And, according to material rules, the raised button size is fixed.

You don't want that behavior, therefore you can use a widget of the second type to override the button constraints.


Anyway, if you need this a lot, consider either creating a new widget which does the job for your. Or use MaterialButton, which possess a height property.

+40

i would recommend using a MaterialButton, than you can do it like this:

new MaterialButton( 
 height: 40.0, 
 minWidth: 70.0, 
 color: Theme.of(context).primaryColor, 
 textColor: Colors.white, 
 child: new Text("push"), 
 onPressed: () => {}, 
 splashColor: Colors.redAccent,
)

使用minWidth並不完全回答設置寬度的問題。在這裡使用Wrap父窗口小部件可能會有所幫助。--AlanKley 5月29日15:55

+20

This piece of code will help you better solve your problem, as we cannot specify width directly to the RaisedButton, we can specify the width to it's child

double width = MediaQuery.of(context).size.width;
var maxWidthChild = SizedBox(
            width: width,
            child: Text(
              StringConfig.acceptButton,
              textAlign: TextAlign.center,
            ));

RaisedButton(
        child: maxWidthChild,
        onPressed: (){},
        color: Colors.white,
    );
+10

You need to use an Expanded Widget. But, if your button is on a column, the Expanded Widget fills the rest of the column. So, you need to enclose the Expanded Widget within a row.

Row(children: <Widget>[
Expanded(
  flex: 1,
  child: RaisedButton(
    child: Text("Your Text"),
      onPressed: _submitForm,
    ),
  ),),])

“擴展你” - 你的意思是擴展的小部件? - Yasir 1月30日0:10

+10

If you want globally change the height and the minWidth of all your RaisedButtons, then you can override ThemeData inside your MaterialApp:

 @override
  Widget build(BuildContext context) {
    return MaterialApp(
       ...
       theme: ThemeData(
       ...
       buttonTheme: ButtonThemeData(
          height: 46,
          minWidth: 100,
       ),
    ));
  }

這就是我想要的。十分感謝! - chazefate 5月27日6:11

固定它。編輯你的評論 - ThinkDigital 18年5月28日19:43

這可以在後台實現嗎?就像我有一個待執行的任務隊列等待互聯網,但應用程序已關閉? - Vidor Vistrom 18年10月6日16:23

請注意,google.com在中國境內無法訪問,因此如果在中國使用,該示例將會掛起。為了擴大您的受眾群體,請避免使用google.com並使用example.com。final result = await InternetAddress.lookup('example.com'); - Questionare232 2月28日21:55

0

If you want the RainseButton to take up the space in parent, please try Expanded Widget

擴展只有在父母支持您的情況下才能使用。 - CopsOnRoad 18年11月25日13:44

我把第一個代碼放在Main.dart中並嘗試使用HomePage,但這會發生以下錯誤無法加載源'dart:async / broadcast_stream_controller.dart': 。 - Rajesh Jr. 18年12月20日16:35

測試了代碼並且它對我有用我需要更多信息來幫助我。 - dennmat 18年12月21日0:40

啊,好吧,我明白了。因此,對於您將來的參考,您發布的錯誤只是編輯器試圖打開它認為發生錯誤的文件。編輯器調試控制台/堆棧跟踪面板中應該提供真正的錯誤。所以我想runApp返回我認為它將運行整個程序生活。看來這是主要的,這裡並不是必需的,所以只需刪除connectionStatus.dispose(),假設你在main()中設置它,如上所述。將更新帖子並鏈接到github示例。 - dennmat 18年12月21日4:46

要檢測是否正在切換wifi或蜂窩電話,您只需要顫動連接。此包裝器在切換發生後檢查連接。但不會提醒每個網絡的變化。如果您正在使用模擬器切換飛機模式是丟失互聯網連接的最簡單方法。如果您使用的是實際設備,則必須確保您仍未連接到包含數據的移動網絡。 - dennmat 18年12月21日14:47

有幾個選項,你可以修改上面的使用Timer來經常測試。或者只是使用Timer實用程序進行頻繁測試。請參閱:api.dartlang.org/stable/2.1.0/dart-async/Timer-class.html另一個選項是在發送每個請求之前測試連接。雖然看起來你可能正在尋找像websockets這樣的東西。無論如何祝你好運 - dennmat 12月29日'18在3:09

0

you can do as they say in the comments or you can save the effort and work with RawMaterialButton . which have everything and you can change the border to be circular and alot of other attributes. ex shape(increase the radius to have more circular shape)

shape: new RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),//ex add 1000 instead of 25

and you can use whatever shape you want as a button by using GestureDetector which is a widget and accepts another widget under child attribute. like in the other example here

GestureDetector(
onTap: () {//handle the press action here }
child:Container(

              height: 80,
              width: 80,
              child:new Card(

                color: Colors.blue,
                shape: new RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
                elevation: 0.0,                
              child: Icon(Icons.add,color: Colors.white,),
              ),
              )
)
0
votes
answers
25 views
+10

檢查Flutter應用程序上是否有可用的Internet連接

我有一個網絡電話要執行。但在此之前,我需要檢查設備是否具有互聯網連接。 這是我到目前為止所做的: var connectivityResult = new Connectivity().checkConnectivity();// User defined class if (connectivityResult == ConnectivityResult.mobile || connectivityResult == ConnectivityResult.wifi) {*/ this.getData(); } else { neverSatisfied(); } 以上方法不起作用。
沙发
0

Following @dennmatt 's answer, I noticed that InternetAddress.lookup may return successful results even if the internet connection is off - I tested it by connecting from my simulator to my home WiFi, and then disconnecting my router's cable. I think the reason is that the router caches the domain-lookup results so it does not have to query the DNS servers on each lookup request.

Anyways, if you use Firestore like me, you can replace the try-SocketException-catch block with an empty transaction and catch TimeoutExceptions:

try {
  await Firestore.instance.runTransaction((Transaction tx) {}).timeout(Duration(seconds: 5));
  hasConnection = true;
} on PlatformException catch(_) { // May be thrown on Airplane mode
  hasConnection = false;
} on TimeoutException catch(_) {
  hasConnection = false;
}

Also, please notice that previousConnection is set before the async intenet-check, so theoretically if checkConnection() is called multiple times in a short time, there could be multiple hasConnection=true in a row or multiple hasConnection=false in a row. I'm not sure if @dennmatt did it on purpose or not, but in our use-case there were no side effects (setState was only called twice with the same value).

板凳
0

I've created a package that (I think) deals reliably with this issue.

The package on pub.dev

The package on GitHub

Discussion is very welcome. You can use the issues tracker on GitHub.


I no longer think this below is a reliable method:


Wanna add something to @Oren's answer: you should really add one more catch, which will catch all other exceptions (just to be safe), OR just remove the exception type altogether and use a catch, that deals with all of the exceptions:

Case 1:

try {
  await Firestore.instance
    .runTransaction((Transaction tx) {})
    .timeout(Duration(seconds: 5));
  hasConnection = true;
} on PlatformException catch(_) { // May be thrown on Airplane mode
  hasConnection = false;
} on TimeoutException catch(_) {
  hasConnection = false;
} catch (_) {
  hasConnection = false;
}

or even simpler...

Case 2:


try {
  await Firestore.instance
    .runTransaction((Transaction tx) {})
    .timeout(Duration(seconds: 5));
  hasConnection = true;
} catch (_) {
  hasConnection = false;
}
43
votes
answers
38 views
+10

顫動 - 建立遊戲的良好基礎?

我打算建立一個手機遊戲。好吧,我想過使用Flutter。它當然會涉及互動,播放聲音,但沒有花哨的物理系統。你是否認為在這種情況下使用Flutter是一個好主意(它更適合學習它的目的)或者它是否為時尚早,我是否應該堅持使用我可以使用的遊戲引擎? 提前致謝
沙发
+60
+50

https://play.google.com/store/apps/details?id=com.newsvoice.newsvoice is an example Flutter app already published to the Play store.

Google and others are reportedly already working on production apps. You need to be aware that breaking changes in the API are to be expected.

The recently introduced plugin system should allow to implement features with missing direct support in Dart, with native code without adding much complexity.

See also

謝謝,我肯定會給你一個公平的嘗試,特別是你提供的音頻插件...... - OhMad 2017年5月8日18:14

網站也撲了嗎?newsvoice.com - Dede 7月28日'18在12:43

不明白你的意思。Flutter無法在瀏覽器中運行。 - GünterZöchbauer18年7月29日6:38

+280

Flame is a simple game engine for Flutter. You can quickly get a simple game up following the readme, and there are a few tutorials, docs and examples to fiddle around. It provides you with sprites (and sprite sheets), audio, text, game loop, component based system, input handling, box2d integration and more.

You can run this sample game I created using an older version of Flame to see it in action.

Disclaimer: I created Flame.

太好了!但是如何在Google Play遊戲服務中使用扑騰呢?我找不到任何實現。有關於此的消息嗎? - user3833732 1月14日22:03

嗨,@ user3833732!我還提供了一個lib來提供GPGS集成:github.com/luanpotter/play_games。它為您提供GPGS登錄,成就和雲保存(到目前為止)。它可以與Flame一起使用和集成,我們在發布的遊戲中使用它。但是,對於Android,我們希望與Apple等效產品集成。 - Luan Nico 1月22日22:30

+50

You might also want to check out https://github.com/vlidholt/flutter_sprites a complete sprite library for Flutter. Specifically for writing 2D games. There is also a version of Box2D written in Dart that works with Flutter.

太棒了,謝謝:) - OhMad 2017年5月10日13:15

Flutter Sprites現在被稱為SpriteWidget - 用於顫動的2D遊戲引擎。支持並更新它以使用最新版本的Flutter。 - Vik Mar 18年1月15日10:05

+30

Some devs are currently playing with Flutter and get some interesting results. See here https://gfycat.com/HomelyFlickeringApisdorsatalaboriosa

看起來非常有趣,謝謝 - OhMad 2017年5月10日13:15

+10

I've been thinking of building an ECS game engine that should allow creation of games written for web to be easily ported to Flutter. I've architected all the classes out in my head:

  • Game
  • GameWorld
  • GameSystem
  • TransformSystem (contains data on Rotate/Scale/Shear)
  • Box2dPhysics
  • DraggableSystem
  • GameUtils
  • TweenLib
  • AssemblageLib
  • TileMapUtils
  • RenderSystemInterface

All of these classes would be exactly the same for the Flutter version of a game and the browser version of a game. The only system that would have to differ is if a developer absolutely wanted to use Flutter ui elements in the mobile version of the game (certainly a nice thing to have).

There are two things that would be more difficult to port and I haven't quite figured it out yet.

The first thing is how to draw text for things like dialog boxes should be done differently between Web and Flutter. There might have to be a FlutterTextSystem and a WebTextSystem that are incompatible. The second thing is the fact that I would be able program the WebRendererSystem to use GLSL shaders, but this is in fact impossible to do at the moment with Flutter. Any common interface between the two types of renderers would have to cut features to accommodate Flutter.

40
votes
answers
40 views
+10

顫動角半徑與透明背景

下面是我希望渲染具有透明背景的圓角容器的代碼。 return new Container( //padding: const EdgeInsets.all(32.0), height: 800.0, //color: const Color(0xffDC1C17), //color: const Color(0xffFFAB91), decoration: new BoxDecoration( color: Colors.green, //new Color.fromRGBO(255, 0, 0, 0.0), borderRadius: new BorderRadius.only( topLeft: const Radius.circular(40.0), topRight: const Radius.circular(40.0)) ), child: new Container( decoration: new BoxDecoration( color: Colors.blue, borderRadius: new BorderRadius.only( topLeft: const Radius.circular(40.0), topRight: const Radius.circular(40.0)) ), child: new Center( child: new Text("Hi modal sheet"), ) ), 然而,這是它呈現的內容,它呈現一個圓角半徑的白色容器(預期透明)。有幫助嗎?
沙发
+260

If you wrap your Container with rounded corners inside of a parent with the background color set to Colors.transparent I think that does what you're looking for. If you're using a Scaffold the default background color is white. Change that to Colors.transparent if that achieves what you want.

        new Container(
          height: 300.0,
          color: Colors.transparent,
          child: new Container(
              decoration: new BoxDecoration(
                  color: Colors.green,
                  borderRadius: new BorderRadius.only(
                      topLeft: const Radius.circular(40.0),
                      topRight: const Radius.circular(40.0))),
              child: new Center(
                child: new Text("Hi modal sheet"),
              )),
        ),
板凳
+60

It's an old question. But for those who come across this question...

The white background behind the rounded corners is not actually the container. That is the canvas color of the app.

TO FIX: Change the canvas color of your app to Colors.transparent

Example:

return new MaterialApp(
  title: 'My App',
  theme: new ThemeData(
    primarySwatch: Colors.green,
    canvasColor: Colors.transparent, //----Change to this------------
    accentColor: Colors.blue,
  ),
  home: new HomeScreen(),
);

最好的答案,這應該是最好的答案。 - Alvin Quezon Jun 4於9:14

地板
+60

If you want to round corners with transparent background, the best approach is using ClipRRect.

return ClipRRect(
  borderRadius: BorderRadius.circular(40.0),
  child: Container(
    height: 800.0,
    width: double.infinity,
    color: Colors.blue,
    child: Center(
      child: new Text("Hi modal sheet"),
    ),
  ),
);

這工作..但在我的容器的末端,半徑os平方:imgur.com/a/Qb5kaVW。你可以幫助我? - Augusto 1月17日11:07

@Augusto你能展示你的代碼嗎? - Dat Nguyen 1月18日6:30

4楼
+20
/// Create the bottom sheet UI
  Widget bottomSheetBuilder(){
    return Container(
      color: Color(0xFF737373), // This line set the transparent background
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
            borderRadius: BorderRadius.only(
                topLeft: Radius.circular(16.0),
                topRight: Radius.circular( 16.0)
            )
        ),
        child: Center( child: Text("Hi everyone!"),)
      ),
    );
  }

Call this to show the BotoomSheet with corners:

/// Show the bottomSheet when called
  Future _onMenuPressed() async {
    showModalBottomSheet(
        context: context,
        builder: (widgetBuilder) => bottomSheetBuilder()
    );
  }
38
votes
answers
36 views
+10

如何在Navigator中使用BottomNavigationBar?

顫振畫廊例子BottomNavigationBar使用Stack的FadeTransitions中的身體Scaffold。 如果我們可以使用a來切換頁面,我覺得它會更乾淨(並且更容易製作動畫)Navigator。 這有什麼例子嗎?
沙发
+360
int index = 0;

@override
Widget build(BuildContext context) {
  return new Scaffold(
    body: new Stack(
      children: <Widget>[
        new Offstage(
          offstage: index != 0,
          child: new TickerMode(
            enabled: index == 0,
            child: new MaterialApp(home: new YourLeftPage()),
          ),
        ),
        new Offstage(
          offstage: index != 1,
          child: new TickerMode(
            enabled: index == 1,
            child: new MaterialApp(home: new YourRightPage()),
          ),
        ),
      ],
    ),
    bottomNavigationBar: new BottomNavigationBar(
      currentIndex: index,
      onTap: (int index) { setState((){ this.index = index; }); },
      items: <BottomNavigationBarItem>[
        new BottomNavigationBarItem(
          icon: new Icon(Icons.home),
          title: new Text("Left"),
        ),
        new BottomNavigationBarItem(
          icon: new Icon(Icons.search),
          title: new Text("Right"),
        ),
      ],
    ),
  );
}

You should keep each page by Stack to keep their state. Offstage stops painting, TickerMode stops animation. MaterialApp includes Navigator.

通過此實現,後退按鈕不適用於訪問以前的Offstage小部件。有沒有辦法支持這個? - RafaelHamasaki 18年4月2日2:56

@RafaelHamasaki你可以使用docs.flutter.io/flutter/widgets/WidgetsBindingObserver / ...處理後退按鈕 - najeira 18年4月2日在3:43

@CodeGrue我使用TickerMode來停止未顯示的小部件的動畫。 - najeira 18年4月2日在3:46

@najeira是的,這就是我最終做的事情。太糟糕了,我必須保持自己的“導航”歷史。不管怎麼說,還是要謝謝你! - RafaelHamasaki 18年4月2日16:28

板凳
+20

Here is example:

  int _currentIndex = 0;


  Route<Null> _getRoute(RouteSettings settings) {
    final initialSettings = new RouteSettings(
        name: settings.name,
        isInitialRoute: true);

    return new MaterialPageRoute<Null>(
        settings: initialSettings,
        builder: (context) =>
        new Scaffold(
          body: new Center(
              child: new Container(
                  height: 200.0,
                  width: 200.0,
                  child: new Column(children: <Widget>[
                    new Text(settings.name),
                    new FlatButton(onPressed: () =>
                        Navigator.of(context).pushNamed(
                            "${settings.name}/next"), child: new Text("push")),
                  ],
                  ))
          ),
          bottomNavigationBar: new BottomNavigationBar(
              currentIndex: _currentIndex,
              onTap: (value) {
                final routes = ["/list", "/map"];
                _currentIndex = value;
                Navigator.of(context).pushNamedAndRemoveUntil(
                    routes[value], (route) => false);
              },
              items: [
                new BottomNavigationBarItem(
                    icon: new Icon(Icons.list), title: new Text("List")),
                new BottomNavigationBarItem(
                    icon: new Icon(Icons.map), title: new Text("Map")),
              ]),
        ));
  }

  @override
  Widget build(BuildContext context) =>
      new MaterialApp(
        initialRoute: "/list",
        onGenerateRoute: _getRoute,
        theme: new ThemeData(
          primarySwatch: Colors.blue,
        ),
      );

You can set isInitialRoute to true and pass it to MaterialPageRoute. It will remove pop animation.

And to remove old routes you can use pushNamedAndRemoveUntil

Navigator.of(context).pushNamedAndRemoveUntil(routes[value], (route) => false);

To set current page you can have a variable in your state _currentIndex and assign it to BottomNavigationBar:

有趣。BottomNavigationBar是否會在整個導航過程中發揮作用?我還需要它來反映當前頁面。 - 保羅7月21日在13:22

BottomNavigationBar並沒有堅持,我們粗略地創造每一次新的,但具有正確的狀態。 - 德國Saprykin於17年7月21日在13:27

更新了當前指數的例子 - 德國Saprykin於17年7月21日在13:34

78
votes
answers
42 views
+10

Flutter:Widget構建完成後運行方法

我希望能夠在Widget完成構建/加載後運行函數,但我不確定如何。我目前的用例是檢查用戶是否經過身份驗證,如果沒有,則重定向到登錄視圖。我不想在之前檢查並推送登錄視圖或主視圖,它需要在主視圖加載後發生。有什麼我可以用來做這個嗎?
沙发
+530

You could use

https://github.com/slightfoot/flutter_after_layout

which executes a function only one time after the layout is completed. Or just look at its implementation and add it to your code :-)

Which is basically

  void initState() {
    super.initState();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => yourFunction(context));
  }

謝謝@thomas你的ans對我很有幫助。我在兩天之前就開始研究這個問題了 再次感謝你非常好的工作 - 拉文德拉Bhanderi 18年6月15日在10:45

請參閱@ anmol.majhail答案:WidgetsBinding.instance.addPostFrameCallback((_)=> yourFunciton(context)); 不再工作 - Pablo Insua 3月26日12:34

板凳
+190

UPDATE:

The Code Mentioned is no Longer Working now :

Not Working:

WidgetsBinding.instance
        .addPostFrameCallback((_) => yourFunction(context));

Working Code:

import 'package:flutter/scheduler.dart';

SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));

第二個不再有效。NoSuchMethodError(NoSuchMethodError:方法'addPostFrameCallback'在null上調用。接收者:null - Oliver Dixon Jun 2 at 17:13

對我來說都是工作。 - 雨果帕索斯6月5日19:55

地板
+40

If you are looking for ReactNative's componentDidMount equivalent, Flutter has it. It's not that simple but it's working just the same way. In Flutter, Widgets do not handle their events directly. Instead they use their State object to do that.

class MyWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => MyState(this);

  Widget build(BuildContext context){...} //build layout here

  void onLoad(BuildContext context){...} //callback when layout build done
}

class MyState extends State<MyWidget>{

  MyWidget widget;

  MyState(this.widget);

  @override
  Widget build(BuildContext context) => widget.build(context);

  @override
  void initState() => widget.onLoad(context);
}

State.initState immediately will be called once upon screen has finishes rendering the layout. And will never again be called even on hot reload if you're in debug mode, until explicitly reaches time to do so.

從我的示例中,您可以使用StatefulWidget類來處理它的State對象,就像StatelessWidget一樣,但我強烈不推薦它。我還沒有發現任何問題,但請盡量在State對像中實現一切 - jerinho 2月27日13:45

4楼
+20

Flutter 1.2 - dart 2.2

According with the official guidelines and sources if you want to be certain that also the last frame of your layout was drawned you can write for example:

import 'package:flutter/scheduler.dart';

void initState() {
   super.initState();
   if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) {
        SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));
   }
}

對我來說,這不起作用,因為在initState()時間我得到SchedulerPhase與SchedulerPhase.idle值...它實際工作的是在build()中添加該檢查 - Alessio 4月24日6:38