トラックパッドを使わずVimライクにキーボード操作するための方法を模索しています
最近Vimmerになりましたnnsnicoです。
Vimの良さを知ったのは春のインターンシップでメンターの方がIdeaVimを使用していたことがきっかけでした。ターミナルいじりが若干の趣味になりつつあるこの頃でしたので、興味本位でVimを触ってみたところ指をチャカチャカ動かさずにタイピングできることの良さにハマりました!!!!
そんなこんなでVimにハマりすぎた僕は思います。「他のアプリもVimですべて済ませてぇなぁ」と。
その方法を探しています。
現状の僕の環境は以下の感じです
アプリケーションの起動
- Alfred
- 言わずとしれたランチャーアプリ。Spotlightよりもシンプルで見やすいのでこちらを使用しています
- アプリの切り替えもすべてこれに頼っています()
ブラウザー
- VivaldiにSurfingKeysのエクステンションをつけています。
エディター
プラグインなど設定は僕のdotfiles内にあります
もっといろんなアプリをVimっぽく操作したいんだYO
これだけでも十分満足なんですが、欲を言うとブラウザ以外にもっともっと他のアプリもすべてVimライクな操作で解決できる方法を探しています。例えばシステム設定画面の操作を十字キーじゃなくhjklでやるみたいな。
KarabinerのVim風keybindingなども試してみましたがモードの切替の反応が微妙に悪かったのでやめました...
Vimのキーバインディングを行うアプリもいろいろ試しましたがSurfingKeysと競合しあってカオスな挙動を見せたりしてんほぉぉってなった
汎用的にVim風で操作できて一部のアプリでは機能を無視してくれる。そんなキーバインディングアプリがあれば最強なんだけどなぁ。まあSurfingKeysを使うのやめたらすぐに解決できる話なんだけど
FlutterとReactNativeを両方使った感想をお話しする
どうも。@nnsnicoです。
今週末にAndroid関連のLT会があるのでその資料を作る前にどんなことを話そうかを整理する目的でここに話すことを書いておきます。
はじめに
最近(?)なにかと流行っているのではないかという感じのクロスプラットフォームアプリのフレームワーク。わざわざAndroidとiOSで書き分けなくても、1つのプログラミング言語で同じもの作れるなんてすごくない?と思って興味を持ち始めました。
フレームワーク自体はたくさんあるのですがどれがどういった良さ悪さを持っているのかはさっぱりだし、文献がすくねぇ(日本語で書いてあるものはおろか英語も公式コミュニティしか盛り上がってない)からいざ試そうにも試しにくい
今回お話しすることはそんな数あるフレームワークの中でもまあまあよさげあさげなFlutterとReactNativeを使ってUIも機能もほぼ同じのアプリを作ってみた感想をメリットとデメリットを添えてお話しすることで少しでも触ってもらえるきっかけになってもらえればと思います。
全く知らない人向けにお話しするので、両フレームワークの簡単な説明もします。
つくったもの
なるべく実用性があると興味がわきやすいと思ったので、API通信を行ってデータを表示するシンプルなものを作ることを目標にしました。
今回はQiita API v2を使用しました。
主な仕様としては、
- Home画面に新規投稿順で記事がリスト表示される
- 投稿者IDと投稿者のプロフィール画像、記事タイトル、いいねカウント
- リストを押すと記事の詳細へ遷移して記事の内容がマークダウンで表示される
- タイトルはCoordinatorLayoutのようにToolbarが伸びたり縮んだりする
よくある感じのアプリです。
Flutterについて
FlutterはGoogleが開発するクロスプラットフォームで動くフレームワークです。Googleが開発しているだけあって、マテリアルデザインを採用した部品を階層的に組み込んでいくコーディングが特徴です。開発言語は同じくGoogleが開発しているDartという言語です。DartはざっくりいうとJavaみたいなJavaScriptです。詳しくは以下を見てください。
Dart programming language | Dart
Flutter - Beautiful native apps in record time
ReactNative
ReactNativeはfacebookが開発するフレームワークです。もともとはReact.jsというWebのフレームワークだったのですが、それをネイティブ向けに作り直したものです。なので書いているコードはReact.jsです。開発言語はJavaScriptです。
JavaScriptであれば動くのでJavaScriptにクロスコンパイルするaltJSでも基本できます。よくある例だとTypeScriptで開発する人はいたりします。僕もします。いい意味でヤバイ人とかだとScala.jsとかで開発を試みた人もいることを聞いたことがあります。Flutterの開発言語であるDartもaltJSなので動くかもしれないです。React.jsはあるみたいです。活発じゃないみたいですが
React Native · A framework for building native apps using React
https://github.com/cleandart/react-dart
Flutterでつくる
Flutterでつくります。ソースコードは以下にあります。
開発にあたって、@konifarさんのdroidkaigi2018のFlutterアプリを参考にしました。そちらのソースコードも添えて見てみるといいかもしれません。
全部解説するとすごい長文になるので、特徴をかいつまんで説明します。
Flutterはレイアウト、ボタン、テキストなどの部品を階層ごとに並べて描画します。また、それらの部品は大きく分けて状態を持つ部品(StatefulWidget)と持たざる部品(StatelessWidget)に分けます。
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'QiitaMitsukeTatter', theme: themeData, home: MyHomePage(title: 'Home'), ); } }
StatefulWidgetはStatefulWidgetの他に、その状態をState
class MyListItem extends StatefulWidget { MyListItem({Key key, @required this.topic}) : super(key: key); final Topic topic; // state @override _MyListItem createState() => _MyListItem(); } class _MyListItem extends State<MyListItem> { @override Widget build(BuildContext context) { return Container( child: ListTile( leading: CircleAvatar( backgroundImage: (widget.topic.user.imageUrl != null) ? NetworkImage(widget.topic.user.imageUrl) : null, ), ...
また、ThemeDataクラスを各コンポーネントに埋め込むことでそのまんまそのカラーが埋め込まれます
import 'package:flutter/material.dart'; final ThemeData themeData = ThemeData( brightness: Brightness.light, primaryColor: Colors.lightGreen, primaryColorBrightness: Brightness.dark, accentColor: Colors.indigoAccent, dividerColor: Colors.grey[300], backgroundColor: Colors.grey[100], secondaryHeaderColor: Colors.white, );
primariColorとかaccentColorをここで選択できるのが良いですね このような描画される部品たちはカタログとして公式が載せているので大変やさしいです
Material Components Widgets - Flutter
プロジェクトの中も少し解説します。Flutterのプロジェクトは/lib配下にメインのソースコードがあります。ライブラリを追加したいときはpubspec.yaml内のdependenciesにぶち込めばいいです。
ディレクトリの階層も単純です。APIの呼び出しをscreen -> repository -> apiと介して呼び出し、結果のJsonをmodelに入れ、screenでmodelを見て描画するだけとなっています。今回のアプリでは特別なアーキテクチャを使ったわけではありませんが、Reduxなどのサポートもされているようです。
Flutterのすこし不便な点は、部品すべてがマテリアルデザインに凝っちゃうのでiOSでマテリアルデザインにしたくない時は採用しにくいです
ReactNativeでつくる
ReactNativeでつくります。ソースコードは以下にあります。
プロジェクトのメインは/src配下にあります。ライブラリなどはpackage.json内です。 アーキテクチャはRedux + Redux-sagaを使用しました。この辺のお話はしないつもりです。
主要な画面たちはcomponents配下にあります。Androidエンジニアの方々だと、Viewの書き方がXMLライクなので親しみがあるかもしれません。
FlatListでデータをリスト描画しています。
class HomeScreen extends React.Component { static navigationOptions = { title: 'Home', }; render() { const { pressListItem, topics } = this.props.screenProps; return ( <View> <StatusBar backgroundColor="#689F38FF" barStyle="light-content" /> <FlatList data={topics} extraData={topics} keyExtractor={(item, index) => String(index)} renderItem={({ item }) => ( <ListItem item={item} pressListItem={pressListItem} /> )} /> </View> ); }
もともとがWebのフレームワークなだけあって、FlexやCSS(ライクのもの)をViewとして扱うことができます。Androidの場合だと、ライブラリを追加しないと使うことができないのでありがたいです
const styles = StyleSheet.create({ header: { position: 'absolute', top: 0, left: 0, right: 0, backgroundColor: '#8BC34AFF', overflow: 'hidden', justifyContent: 'flex-end', alignItems: 'flex-start', }, ... fill: { flex: 1, }, ...
ReactNativeの不便な点は、Flutterと違って複雑なViewだと見にくいコードになりがちなことです。今回のコードのDetailScreenが一番の例かもしれません。
... return ( <View style={styles.fill}> <StatusBar backgroundColor="#689F38FF" barStyle="light-content" /> <ScrollView style={[styles.fill]} scrollEventThrottle={16} onScroll={Animated.event([ { nativeEvent: { contentOffset: { y: this.state.animateHeader } }, }, ])} > <View style={[styles.scrollViewContent, { minHeight: height - Header.HEIGHT - StatusBar.currentHeight }]}> <Markdown> {topic.body} </Markdown> </View> </ScrollView> <Animated.View style={[styles.header, { height: headerHeight }]}> <Animated.Text style={[styles.title, { opacity: opacityContent }]}> {topic.title} </Animated.Text> <View style={{ flexDirection: 'row', alignItems: 'flex-end', padding: 8 }}> <Animated.Image style={[styles.profileImage, { opacity: opacityContent, }]} source={{ uri: topic.user.profile_image_url }} /> <Animated.Text style={[styles.userName, { opacity: opacityContent }]}> {topic.user.id} </Animated.Text> </View> </Animated.View> </View > ); ...
まとめ
自分なりのFlutterとReactNativeのメリット・デメリットをまとめます
Flutter
メリット
デメリット
- Stateful?Stateless?なにそれおいしいの?
- ちゃんとしたアーキテクチャでつくりたいかもしれない
ReactNative
メリット
- React.jsの知識がそのまんま使える!
- XMLライクにViewを書ける!
- Reduxは分かってしまえば最強
- ライブラリ(パッケージ)が豊富
- アプデが盛ん
デメリット
- Reduxを理解するまでに地味に時間がかかる
- たたみかけるように副作用を扱うためのライブラリの仕様も知る必要がある
- Viewが複雑になると途端に見にくくなる(Animationを盛り込むとすごい)
クロスプラットフォーム全体としての感想は、どちらもまだアプリとして安定したパフォーマンスを出せていないことですね。あと一生これがサポートされるのか?という不安もあります。
完全なアプリとして採用するのではなく、プロトタイプとしてさらっと作れることが最大のメリットだと感じました。
他にも色々あると思いますが、ざっくりにはこれぐらいだと思います。
以上、ぐだぐだとそれぞれのアプリを作成した内容を書きましたが、これだけ書いてすぐ思ったのが「ただただ長くてわかりにくいな...」ということでした♨️
資料は作ったらここにあげるかもしれないです。おしまい
スカラシップスポンサーとしてDroidKaigi 2018へ行ってまいりました
はじめまして。@nnsnicoです。 2月8〜2月9日にかけて行われました「DroidKaigi 2018」へ参加したレポートとその経緯についてお話していきたいと思います
経緯
今回のDroidKaigi 2018では、学生のためのオトクなプランが提供されていることを公式ページより知りました。それが、タイトルにも書きました「スカラシップスポンサー」というものでした。 何がオトクかというと...
- 旅費:5万円を上限に補助
- チケット:100%の割引
ほぼタダ。去年からお金を理由にDroidKaigiに参加することを断念してた僕としては何よりも嬉しいプランでした😄
申し込みは、アンケートとインタビューとのことなのでこれらをやった結果...嬉し恥ずかしながらスカラシップスポンサーとしての参加を認めてもらえました。感無量です。
これでようやく1年に渡って行きたかったDroidKaigiへの参加をすることができました。
参加レポート
今回のDroidKaigiはアーキテクチャに関するお話が割と多い気がしました。僕自身、アーキテクチャにとても興味を持っているマンでしたので、とても勉強になるセクションばかりで嬉しかったです。
2日にかけて行われましたDroidKaigi 2018のセクションの中でも僕が特に大きく知見を得れたと感じられたセクションを感想と共に紹介したいと思います。
How to improve your MVP architecture and tests@kiriminさん
@kiriminさんのMVPアーキテクチャに関するお話です。
MVPによる開発は一度したことのある開発でしたが、MVVMが盛んなこの時期にMVPをフルに活用して開発したお話を聞けたのは大変貴重でした。
AndroidにおけるModel-View-Intentアーキテクチャ@Benoit Quenaudonさん
@Benoit QuenaudonさんのMVIアーキテクチャのお話です。
MVIアーキテクチャというものを初めて聞くもので、かつ事前学習をしていなかったので理解できるものかと思っていましたが、単一方向データフロー型のアーキテクチャだと分かってなんとなく理解できました。イベントが割り込んでもちゃんとデータを保持できるのがすごいですね。一度自分でこれを使ってアプリを実装してみたいですね。(スライドが美しくて途中魅入っていました)
Kotlin版CleanArchitectureのテンプレート作ったら爆速開発になった話+α@Keisuke Kiuchiさん
@Keisuke KiuchiさんのKotlinをCAで実装するためのテンプレを作ったお話です。
CAそのものはiOSアプリの開発のために取り入れていたアーキテクチャでしたが、レイヤ分けやクラスの量がとても多くて基盤を作るのが大変に感じました。
このテンプレートで作成することで、基盤のレイヤとクラスを作成されたプロジェクトが作成されるので、実装が爆速になりそうです!
All you need is isolating the domain(How to apply DDD to Android Application Development 2)@yanzmさん
@yanzmさんのDDDをAndroidに盛り込んだお話です。
前回のDroidKaigi 2017のお話の続きです。DDDは設計思想であり、これをどのようにアーキテクチャとして実装するのか難しい部分がありました。
今回はその部分を特に理解することができる機会になったのでよかったです。
エリックエヴァンス本はやく読破しなければ...
コードで見るFlutterアプリの実装@konifarさん
@konifarさんのDroidKaigi 2018アプリをFlutterで実装したお話です。
最近はReact Nativeを触っていることもあってクロスプラットフォームアプリを開発するためのフレームワークを触ることが少し趣味になりつつあるこの頃。konifarさんがFlutterでDroidKaigiのアプリを開発してくれたお話を聞くことでFlutterの良さを深めることができました。
Flutterの開発言語であるDartはJavaっぽいJavaScriptと聞いていたので分かりやすいのでは...!と思っていましたが、Flutterと組み合わせると意外とクセのある言語だなと感じました。(だがそれがいい)
以上、5つしかあげませんでしたが、全てのセクション素晴らしいと思いましたし、本会場で見たかったものも多くありました。
最後に
以上がDroidKaigi 2018の参加レポートでした。僕が得られた知見をまとめました
- 新たなアーキテクチャとその仕組みについて
- Kotlinの詳しい実装パターン
- React Native、Flutterといったクロスプラットフォームアプリフレームワークのコーディング方法や仕組み
今回スカラシップスポンサーとして参加をさせてくださいました協賛企業様であるWantedly様、僕に知見をくださいました全ての登壇者様、DroidKaigi 2018を支えてくれたスタッフのみなさま、そしてなにより今回もDroidKaigi 2018を開催させてくださった代表のmhidaka様、本当にありがとうございました。
最近はAndroid触れていないし、Kotlinもにわかなので頑張って追いつかなくては....😅