Android 颤振,水平航行

Android 颤振,水平航行,android,flutter,Android,Flutter,在Codelab英语单词示例中。。。 iOS导航转换是水平的。。正如您所期望的,一个Segue将在一个UINavigationController中运行。从右到左。。。POP从左到右。 ANDROID,同样的例子是垂直的,从下到上。POP是从上到下的。 我的问题。。。我如何在安卓系统中强制执行水平转换,使其行为类似于iOS?我想我将不得不使用MaterialPageRoute /* Nguyen Duc Hoang(Mr) Programming tutorial channel: ht

在Codelab英语单词示例中。。。 iOS导航转换是水平的。。正如您所期望的,一个Segue将在一个UINavigationController中运行。从右到左。。。POP从左到右。
ANDROID,同样的例子是垂直的,从下到上。POP是从上到下的。
我的问题。。。我如何在安卓系统中强制执行水平转换,使其行为类似于iOS?我想我将不得不使用MaterialPageRoute

    /*
Nguyen Duc Hoang(Mr)
Programming tutorial channel:
https://www.youtube.com/c/nguyenduchoang
Flutter, React, React Native, IOS development, Swift, Python, Angular
* */
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

//Define "root widget"
void main() => runApp(new MyApp());//one-line function
//StatefulWidget
class RandomEnglishWords extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new RandomEnglishWordsState();//return a state's object. Where is the state's class ?
  }
}
//State
class RandomEnglishWordsState extends State<RandomEnglishWords>{
  final _words = <WordPair>[];//Words displayed in ListView, 1 row contains 1 word
  final _checkedWords = new Set<WordPair>();//set contains "no duplicate items"
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    //Now we replace this with a Scaffold widget which contains a ListView
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("List of English words"),
        actions: <Widget>[
          new IconButton(icon: new Icon(Icons.list),
              onPressed: _pushToSavedWordsScreen)
        ],
      ),
      body: new ListView.builder(itemBuilder: (context, index) {
        //This is an anonymous function
        //index = 0, 1, 2, 3,...
        //This function return each Row = "a Widget"
        if (index >= _words.length) {
          _words.addAll(generateWordPairs().take(10));
        }
        return _buildRow(_words[index], index);//Where is _buildRow ?
      }),
    );
  }
  _pushToSavedWordsScreen() {
//    print("You pressed to the right Icon");
    //To navigate, you must have a "route"
    final pageRoute = new MaterialPageRoute(builder: (context) {
      //map function = Convert this list to another list(maybe different object's type)
      //_checkedWords(list of WordPair) => map =>
      // converted to a lazy list(Iterable) of ListTile
      final listTiles = _checkedWords.map( (wordPair) {
        return new ListTile(
          title: new Text(wordPair.asUpperCase,
            style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),),
        );
      });
      //Now return a widget, we choose "Scaffold"
      return new Scaffold(
        appBar: new AppBar(
          title: new Text("Checked words"),
        ),
        body: new ListView(children: listTiles.toList(),),//Lazy list(Iterable) => List
      );
    });
    Navigator.of(context).push(pageRoute);
  }
  Widget _buildRow(WordPair wordPair, int index) {
    //This widget is for each row
    final textColor = index % 2 == 0 ? Colors.red : Colors.blue;
    final isChecked = _checkedWords.contains(wordPair);
    return new ListTile(
      //leading = left, trailing = right. Is is correct ? Not yet
      leading: new Icon(
        isChecked ? Icons.check_box : Icons.check_box_outline_blank,
        color: textColor,
      ),
      title: new Text(
        wordPair.asUpperCase,
        style: new TextStyle(fontSize: 18.0, color: textColor),
      ),
      onTap: () {
        setState(() {
          //This is an anonymous function
          if (isChecked) {
            _checkedWords.remove(wordPair);//Remove item in a Set
          } else {
            _checkedWords.add(wordPair);//Add item to a Set
          }
        });
      },
    );
  }
}

class MyApp extends StatelessWidget {
  //Stateless = immutable = cannot change object's properties
  //Every UI components are widgets
  @override
  Widget build(BuildContext context) {
    //build function returns a "Widget"
    return new MaterialApp(
        title: "This is my first Flutter App",
        home: new RandomEnglishWords()
    );//Widget with "Material design"
  }
}
/*
阮德宏先生
编程教程频道:
https://www.youtube.com/c/nguyenduchoang
颤振、反应、反应本机、IOS开发、Swift、Python、角度
* */
进口“包装:颤振/材料.省道”;
导入“package:english_words/english_words.dart”;
//定义“根控件”
void main()=>runApp(新的MyApp())//单线函数
//状态控件
类RandomEnglishWords扩展StatefulWidget{
@凌驾
状态createState(){
//TODO:实现createState
return new RandomEnglishWordsState();//返回状态的对象。状态的类在哪里?
}
}
//陈述
类RandomEnglishWordsState扩展了状态{
final _words=[];//ListView中显示的单词,一行包含一个单词
final _checkedWords=new Set();//集合包含“无重复项”
@凌驾
小部件构建(构建上下文){
//TODO:实现构建
//现在我们用一个包含ListView的Scaffold小部件替换它
归还新脚手架(
appBar:新的appBar(
标题:新文本(“英文单词列表”),
行动:[
新图标按钮(图标:新图标(Icons.list),
按下按钮:_按保存或屏幕)
],
),
正文:new ListView.builder(itemBuilder:(上下文,索引){
//这是一个匿名函数
//索引=0,1,2,3,。。。
//此函数返回每行=“小部件”
如果(索引>=\u单词长度){
_words.addAll(generateWordPairs().take(10));
}
返回_buildRow(_words[index],index);//哪里是_buildRow?
}),
);
}
_PushToSavedWordScreen(){
//打印(“您按下了右侧图标”);
//要导航,必须有“路线”
最终页面路径=新材料路径(生成器:(上下文){
//映射函数=将此列表转换为另一个列表(可能是不同对象的类型)
//_选中的单词(单词对列表)=>map=>
//已转换为ListTile的惰性列表(Iterable)
final listTiles=\u checkedWords.map((字对){
返回新的ListTile(
标题:新文本(wordPair.asupercase,
样式:新的文本样式(fontSize:20.0,fontWeight:fontWeight.bold),
);
});
//现在返回一个小部件,我们选择“Scaffold”
归还新脚手架(
appBar:新的appBar(
标题:新文本(“勾选文字”),
),
正文:新建ListView(子项:listTiles.toList(),),//惰性列表(Iterable)=>list
);
});
导航器.of(上下文).push(页面路由);
}
小部件构建行(字对字对,int索引){
//此小部件适用于每行
最终文本颜色=索引%2==0?颜色。红色:颜色。蓝色;
final isChecked=\u checkedWords.contains(字对);
返回新的ListTile(
//前导=左,尾随=右。正确吗?还没有
领先:新图标(
isChecked?图标。复选框:图标。复选框\u轮廓\u空白,
颜色:textColor,
),
标题:新文本(
wordPair.asUpperCase,
样式:新的TextStyle(fontSize:18.0,颜色:textColor),
),
onTap:(){
设置状态(){
//这是一个匿名函数
如果(已检查){
_checkedWords.remove(字对);//删除集合中的项
}否则{
_checkedWords.add(字对);//将项添加到集合中
}
});
},
);
}
}
类MyApp扩展了无状态小部件{
//无状态=不可变=无法更改对象的属性
//每个UI组件都是小部件
@凌驾
小部件构建(构建上下文){
//构建函数返回一个“小部件”
返回新材料PP(
标题:“这是我的第一个颤振应用程序”,
首页:新英语单词()
);//带有“材质设计”的小部件
}
}

首先,关于
材料路线
对您的案例没有帮助。以下是官方对此的解释:

MaterialPageRoute很方便,因为它可以转换到新的 使用特定于平台的动画显示屏幕

您看到的这些动画是特定于平台的动画

如果要实现自定义动画,需要使用
PageRouteBuilder
手动实现。这是你可以做到的

这是您的
\u pushtosavedwordscreen
的一个修改版本,它执行从右到左的转换。在谷歌像素上测试

final pageRoute = new PageRouteBuilder(
  pageBuilder: (BuildContext context, Animation animation,
      Animation secondaryAnimation) {
    // YOUR WIDGET CODE HERE
    final listTiles = _checkedWords.map((wordPair) {
      return new ListTile(
        title: new Text(
          wordPair.asUpperCase,
          style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
        ),
      );
    });
    //Now return a widget, we choose "Scaffold"
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Checked words"),
      ),
      body: new ListView(
        children: listTiles.toList(),
      ), //Lazy list(Iterable) => List
    );
  },
  transitionsBuilder: (BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    return SlideTransition(
      position: new Tween<Offset>(
        begin: const Offset(1.0, 0.0),
        end: Offset.zero,
      ).animate(animation),
      child: new SlideTransition(
        position: new Tween<Offset>(
          begin: Offset.zero,
          end: const Offset(1.0, 0.0),
        ).animate(secondaryAnimation),
        child: child,
      ),
    );
  },
);
Navigator.of(context).push(pageRoute);
final pageRoute=新的PageRouteBuilder(
pageBuilder:(构建上下文、动画、,
动画(二级动画){
//您的小部件代码在这里
final listTiles=\u checkedWords.map((字对){
返回新的ListTile(
标题:新文本(
wordPair.asUpperCase,
样式:新的文本样式(fontSize:20.0,fontWeight:fontWeight.bold),
),
);
});
//现在返回一个小部件,我们选择“Scaffold”
归还新脚手架(
appBar:新的appBar(
标题:新文本(“勾选文字”),
),
正文:新列表视图(
子项:listTiles.toList(),
),//惰性列表(Iterable)=>list
);
},
transitionsBuilder:(构建上下文、动画、,
动画辅助动画,小部件子项){
返回幻灯片转换(
职位:新吐温(
开始:常数偏移(1.0,0.0),
结束:偏移0.0,
).制作动画(动画),
子:新幻灯片转换(
职位:新吐温(
开始:Offset.zero,
结束:常数偏移(1.0,0.0),
).制作动画(第二动画),
孩子:池
dependencies:
  flutter:
    sdk: flutter
  english_words:  ^3.1.0 #version 3.1.0 or above
/*
Nguyen Duc Hoang(Mr)
Programming tutorial channel:
https://www.youtube.com/c/nguyenduchoang
Flutter, React, React Native, IOS development, Swift, Python, Angular
* */
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

//Define "root widget"
void main() => runApp(new MyApp());//one-line function
//StatefulWidget
class RandomEnglishWords extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new RandomEnglishWordsState();//return a state's object. Where is the state's class ?
  }
}
//State
class RandomEnglishWordsState extends State<RandomEnglishWords> {
  final _words = <WordPair>[
  ]; //Words displayed in ListView, 1 row contains 1 word
  final _checkedWords = new Set<WordPair>(); //set contains "no duplicate items"
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    //Now we replace this with a Scaffold widget which contains a ListView
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("List of English words"),
        actions: <Widget>[
          new IconButton(icon: new Icon(Icons.list),
              onPressed: _pushToSavedWordsScreen)
        ],
      ),
      body: new ListView.builder(itemBuilder: (context, index) {
        //This is an anonymous function
        //index = 0, 1, 2, 3,...
        //This function return each Row = "a Widget"
        if (index >= _words.length) {
          _words.addAll(generateWordPairs().take(10));
        }
        return _buildRow(_words[index], index); //Where is _buildRow ?
      }),
    );
  }

  _pushToSavedWordsScreen() {
//    print("You pressed to the right Icon");
    //To navigate, you must have a "route"

//======================================================================
//=======  original solution  -  ANDROID transitions Vertically
//    final pageRoute = new MaterialPageRoute(builder: (context) {
//      //map function = Convert this list to another list(maybe different object's type)
//      //_checkedWords(list of WordPair) => map =>
//      // converted to a lazy list(Iterable) of ListTile
//      final listTiles = _checkedWords.map( (wordPair) {
//        return new ListTile(
//          title: new Text(wordPair.asUpperCase,
//            style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),),
//        );
//      });
//      //Now return a widget, we choose "Scaffold"
//      return new Scaffold(
//        appBar: new AppBar(
//          title: new Text("Checked words"),
//        ),
//        body: new ListView(children: listTiles.toList(),),//Lazy list(Iterable) => List
//      );
//    });
//    Navigator.of(context).push(pageRoute);
//  }
    //===========   OLD solution...  ANDROID transitions Vertically
    //==================================================================



    //==================================================================
    //===========   new solution...  transition Horizontal

    final pageRoute = new PageRouteBuilder(
      pageBuilder: (BuildContext context, Animation animation,
          Animation secondaryAnimation) {
        // YOUR WIDGET CODE HERE
        final listTiles = _checkedWords.map((wordPair) {
          return new ListTile(
            title: new Text(
              wordPair.asUpperCase,
              style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
            ),
          );
        });
        //Now return a widget, we choose "Scaffold"
        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Checked words"),
          ),
          body: new ListView(
            children: listTiles.toList(),
          ), //Lazy list(Iterable) => List
        );
      },
      transitionsBuilder: (BuildContext context, Animation<double> animation,
          Animation<double> secondaryAnimation, Widget child) {
        return SlideTransition(
          position: new Tween<Offset>(
            begin: const Offset(1.0, 0.0),
            end: Offset.zero,
          ).animate(animation),
          child: new SlideTransition(
            position: new Tween<Offset>(
              begin: Offset.zero,
              end: const Offset(1.0, 0.0),
            ).animate(secondaryAnimation),
            child: child,
          ),
        );
      },
    );
    Navigator.of(context).push(pageRoute);
  }
  //=========  end of solution
  //=============================================================

    Widget _buildRow(WordPair wordPair, int index) {
      //This widget is for each row
      final textColor = index % 2 == 0 ? Colors.red : Colors.blue;
      final isChecked = _checkedWords.contains(wordPair);
      return new ListTile(
        //leading = left, trailing = right. Is is correct ? Not yet
        leading: new Icon(
          isChecked ? Icons.check_box : Icons.check_box_outline_blank,
          color: textColor,
        ),
        title: new Text(
          wordPair.asUpperCase,
          style: new TextStyle(fontSize: 18.0, color: textColor),
        ),
        onTap: () {
          setState(() {
            //This is an anonymous function
            if (isChecked) {
              _checkedWords.remove(wordPair); //Remove item in a Set
            } else {
              _checkedWords.add(wordPair); //Add item to a Set
            }
          });
        },
      );
    }
  }





class MyApp extends StatelessWidget {
  //Stateless = immutable = cannot change object's properties
  //Every UI components are widgets
  @override
  Widget build(BuildContext context) {
    //build function returns a "Widget"
    return new MaterialApp(
        title: "This is my first Flutter App",
        home: new RandomEnglishWords()
    );//Widget with "Material design"
  }
}