这是我的代码: 我在Android MainActivity中响应键事件,并使用BasicMessageChannel发布关键消息:
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "scroll";
private static final String KEY_LEFT = "keyLeft";
private static final String KEY_RIGHT = "keyRight";
private BasicMessageChannel messageChannel;
private FlutterView flutterView;
private String[] getArgsFromIntent(Intent intent) {
// Before adding more entries to this list, consider that arbitrary
// Android applications can generate intents with extra data and that
// there are many security-sensitive args in the binary.
ArrayList<String> args = new ArrayList<String>();
if (intent.getBooleanExtra("trace-startup", false)) {
args.add("--trace-startup");
}
if (intent.getBooleanExtra("start-paused", false)) {
args.add("--start-paused");
}
if (intent.getBooleanExtra("enable-dart-profiling", false)) {
args.add("--enable-dart-profiling");
}
if (!args.isEmpty()) {
String[] argsArray = new String[args.size()];
return args.toArray(argsArray);
}
return null;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
flutterView = new FlutterView(this);
String[] args = getArgsFromIntent(getIntent());
FlutterMain.ensureInitializationComplete(getApplicationContext(), args);
flutterView.runFromBundle(FlutterMain.findAppBundlePath(getApplicationContext()), null);
messageChannel = new BasicMessageChannel<>(flutterView, CHANNEL, StringCodec.INSTANCE);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
Log.d(TAG, "dispatchKeyEvent: ACTION_DOWN keyCode = " + event.getKeyCode());
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_LEFT:
messageChannel.send(KEY_LEFT);
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
messageChannel.send(KEY_RIGHT);
return true;
default:
break;
}
}
return super.dispatchKeyEvent(event);
}
@Override
protected void onDestroy() {
if (flutterView != null) {
flutterView.destroy();
}
super.onDestroy();
}
@Override
protected void onPause() {
super.onPause();
flutterView.onPause();
}
@Override
protected void onPostResume() {
super.onPostResume();
flutterView.onPostResume();
}
}
当Flutter收到消息时,我调用nextPage()和previousPage()来滚动PageView,它不起作用。但我发现如果我在GestureDetector的onTap()方法中调用nextPage()和previousPage(),它可以工作:
class _Page {
_Page({
this.imagePath,
});
final String imagePath;
}
final List<_Page> _allPages = <_Page>[
new _Page(imagePath: 'images/1.jpg'),
new _Page(imagePath: 'images/2.jpg'),
new _Page(imagePath: 'images/3.jpg'),
new _Page(imagePath: 'images/4.jpg'),
new _Page(imagePath: 'images/5.jpg'),
new _Page(imagePath: 'images/6.jpg'),
];
class ScrollablePageDemo extends StatefulWidget {
@override
_ScrollablePageDemoState createState() => new _ScrollablePageDemoState();
}
class _ScrollablePageDemoState extends State<ScrollablePageDemo>
with SingleTickerProviderStateMixin {
PageController _controller;
static const String _channel = 'scroll';
static const String _emptyMessage = '';
static const String KEY_LEFT = "keyLeft";
static const String KEY_RIGHT = "keyRight";
static const BasicMessageChannel<String> platform =
const BasicMessageChannel<String>(_channel, const StringCodec());
@override
void initState() {
super.initState();
_controller = new PageController(
initialPage: 0, keepPage: true, viewportFraction: 1.0);
platform.setMessageHandler(changePage);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
Future<String> changePage(String message) async {
setState(() {
print(message);
if (message == KEY_RIGHT) {
//here doesn't work
_controller.nextPage(duration: kTabScrollDuration, curve: Curves.ease);
print("tab right: page = " + _controller.page.toString());
} else if (message == KEY_LEFT) {
//here doesn't work
_controller.previousPage(duration: kTabScrollDuration, curve: Curves.ease);
print("tab left: page = " + _controller.page.toString());
}
});
return _emptyMessage;
}
PageView buildPageView() {
return new PageView(
controller: _controller,
children: _allPages.map((_Page page) {
return new Container(
key: new ObjectKey(page.imagePath),
padding: const EdgeInsets.all(12.0),
child: new Card(
child: new Image.asset(page.imagePath, fit: BoxFit.fill)));
}).toList(),
);
}
@override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: () {
print('Listen PageView');
//here works
_controller.nextPage(duration: kTabScrollDuration, curve: Curves.ease);
},
child: new Scaffold(
appBar: new AppBar(
title: new Text('PageView'),
),
body: buildPageView()));
}
}
void main() {
runApp(new MaterialApp(
title: 'Flutter Study',
home: new ScrollablePageDemo(),
));
}
答案 0 :(得分:0)
问题在于setState
内的changePage
方法。只要状态设置,setState
就会调用build
方法。因此,只要调用setState
,页面就会再次构建。您只需从setState
方法中删除changePage
。
示例:
Future<String> changePage(String message) async {
print(message);
if (message == KEY_RIGHT) {
_controller.nextPage(duration: kTabScrollDuration, curve: Curves.ease);
print("tab right: page = " + _controller.page.toString());
} else if (message == KEY_LEFT) {
_controller.previousPage(duration: kTabScrollDuration, curve: Curves.ease);
print("tab left: page = " + _controller.page.toString());
}
return _emptyMessage;
}
希望有所帮助!