2017-12-20 9 views
0

ここに私のコードは動作しません: 私はAndroidのMainActivityでキーイベントを応答し、キーメッセージ投稿するBasicMessageChannelを使用します。PageControllerで中nextPageメソッド()とpreviousPage()は時々

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をスクロールしますが、それは機能しません。しかし、私はNEXTPAGE()とONTAPでpreviousPage()()GestureDetectorのメソッドを呼び出した場合、それが動作見つける:

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

問題がchangePage内部setState方法です。 setStateは、状態が設定されるたびにbuildメソッドを呼び出します。したがって、setStateが呼び出されるたびにページが再び構築されます。 changePageメソッドからsetStateを削除するだけで済みます。

例:助け

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

願っています!

関連する問題