VimConf 2015に行ってきた。
VimConf 2015に行ってきました。
発表者の方々のスライドへのリンクは次のURLにあります。
http://vimconf.vim-jp.org/2015/#agenda
セッションについては他の方々が紹介していると思うのでそちらにお任せしたいと思います。
申し訳ありません。*1
懇親会
懇親会が始まる前にピザを運ぶのを手伝わさせていただきました。
たくさんのピザを運ぶお手伝いを今までしたことがないので貴重な体験となりました。
このような懇親会に参加するのは初めてなので、どのようにたち振る舞えば良いのかわからなかったのですが
数人の方に話しかけていただきました。本当にありがとうございます。
derisさんに話しかけていただいたのですが、その時すかさずduzzle.vimが好きだということを伝えました。
懇親会ではほとんどVimについて話していないことに気づきました。
それでも非常に楽しいひと時となりました。
終わりに
今回まとめ役をしていただいた@dictavさん、運営の皆さん、発表者の皆さん、会場を貸していただいたmixiさん、ありがとうございました。
是非来年も参加したいと思います!
これで自分のVimConf 2015も終わりです。
*1:自分の不注意でセッションの感想を消してしまいました。
Android Data Bindingを使ってみた。
最近ちょこちょことtechbooster.fmを聞いているのですが、第11回でDataBindingの話をしていて、その存在を知ったのでちょっと使ってみた。
詳しい使い方についてはData Binding Guide | Android Developersに詳しく書いている(はず)です。まだ読んでないです。
以下で出てくるコードはこのサイトに載っているコードです。
準備
appモジュールのbuild.gradleにdataBinding要素を追加する
android { ... dataBinding { enabled = true } }
これだけです。
使い方
DataBindingをするにはlayoutファイルを次のように記述するとcom.example.UserクラスのfirstNameフィールドがTextViewにバインド?される。
<!-- res/layout/main_activity.xml --> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.example.User"/> </data> <LinearLayout ...> <TextView ... android:text="@{user.firstName}"/> </LinearLayout> </layout>
重要な点は4つ。
- ルートタグとして<layout>を使うこと
- <layout>タグの直後に<data>要素を記述すること
- <data>要素の中に<variable>要素を指定し、バインドしたいクラスを指定すること
- バインドしたクラスのフィールドを指定するには@{}構文を使用すること
あとは次のようなコードを記述すればDataBindingが行われる。
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity); User user = new User("Test", "User"); binding.setUser(user); }
ここで出てくるMainActivityBindingクラスはDataBindingライブラリによってコンパイル時に作成されるクラスです。
先ほど、main_activity.xmlを書いたのでMainActivityBindingクラスが生成されています。
このBindingクラスの名前はlayoutファイル名をキャメルケースしたものの末尾にBindingという文字列をくっつけた名前になります。
例えばlayoutファイルの名前がitem_view.xmlであればItemViewBindingクラスが生成されることになります。
感想
すごく簡単にしか使ってないけど、結構便利そう。
下の動画でも言っているけど、RecyclerViewを使うときのAdapterやHolderの記述が簡潔に書ける。
www.youtube.com
他のDataBindingライブラリとしてButterKnifeの存在は知っていたけど、なんとなく使うのを面倒に感じていて今まで使っていなかった。
今回のtechbooster.fmがDataBindingを使うきっかけになりました。非常に感謝です。
これからも少しずつDataBindingを使っていこうと思う。
ImageButtonを使ってみた。
上の画像の再生ボタンのようなボタンを作成したかったので、そのためのメモ。
ImageButton
このようなボタンを作成するためにはImageButtonを使う。これは、その名の通り画像付きのボタンを表す。
例えばこんな感じに表示される。
このImageButtonの結果は次のようなコードで得られる。
... <ImageButton android:id="@+id/click_me_button" android:layout_centerHorizontal="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/click_me" android:tint="@color/colorAccent" android:src="@drawable/ic_action_playback_play" /> ...
見ての通り、通常のButtonにtextの代わりに画像を載せた感じになっている。
最初の画像のように背景を透過させたい場合には、ImageButtonのandroid:background属性にアルファ値がffの値を指定してあげれば良い。
ただ、これだとボタンをクリックした時にボタンが何も反応していないような感じになってしまうので、android:background属性には?android:selectableItemBackgroundや?android:selectableItemBackgroundBorderlessを指定してあげるとボタンをクリックした時に波紋が広がるようなアニメーションが得られる。
これを行うことで次のようにボタンの背景が透過されて表示される。
感想
Android開発では色々と学ぶことが多いので大変だけど、それなりに充実しているので、どんどん学んでいきたい。
ActivityUnitTestCaseでIllegalStateException
Androidのテストを学ぶためにCreating Unit Tests | Android Developersを読みながら、そのサイトに載っているAndroidTestFunを写経していた。その時、ちょっと詰まってしまったのでメモ。
ActivityUnitTestCaseのstartActivity()を起点にした例外
AndroidTestFunプロジェクトのlesson4にLaunchActivityTestクラスがあるのだけれど、そのtestPreconditions()を書いてテストを走らせた時に例外が発生した。testPrecondisions()のコードは次のようなもの。
@MediumTest public void testPreconditions() { //Start the activity under test in isolation, without values for savedInstanceState and //lastNonConfigurationInstance startActivity(mLaunchIntent, null, null); final Button launchNextButton = (Button) getActivity().findViewById(R.id.launch_next_activity_button); assertNotNull("mLaunchActivity is null", getActivity()); assertNotNull("mLaunchNextButton is null", launchNextButton); }
テストのログを見てみると次のようなエラーメッセージが書いてあった。
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
なぜこんな例外が発生するのだろうと思って少し調べてみると、こんなサイトがあった。
Issue 128421 - android - ActivityUnitTestCase startActivity() IllegalStateException - Android Open Source Project - Issue Tracker - Google Project Hosting
どうやら同じような例外が発生している人がいるみたいだった。
このissueでは2つの解決法が提供されていた。
- setActivity()をオーバーライドする方法
- contextを明示的に設定する方法
setActivity()をオーバーライドする方法
@Override protected void setActivity(Activity testActivity) { if (testActivity != null) testActivity.setTheme(R.style.AppTheme); super.setActivity(testActivity); }
contextを明示的に設定する方法
protected void setUp() throws Exception { super.setUp(); ContextThemeWrapper context = new ContextThemeWrapper( getInstrumentation().getTargetContext(), R.style.AppTheme); setActivityContext(context); (...) }
自分の場合、どちらの方法を使っても例外が発生しなくなった。
原因はよくわかっていないけど、とりあえずこれでまた写経を始めることができる。
Notificationをユーザに消されないようにする
AndroidでのNotificationをユーザに消されないようにするには次のようにすれば良い。
NotificationCompat.Builder builder = new NotificationCompat.Builder(context) .setOngoing(true); // このメソッドでtrueを指定する
主な使用用途として考えられるのは、音楽の再生中とかダウンロード中のNotification。
注意としては、setOngoing(true)としている限りNotificationが消えることはないので、音楽の再生やダウンロードが終わったらsetOngoing(false)を指定したNotificationをnotifyする必要があるということ。
追記(2015.11.12)
あまり行儀は良くないのかもしれないけどNotificationクラスのflagsを直接操作してもNotificationを消されないようにできる。
Notification notification = new Notification();
notification.flags |= Notification.FLAG_NO_CLEAR;
GitHub実践入門を読んだ。
今日、友達に頂いたGitHub実践入門を読んだ。読みたい本だったのだけれど、お金が無くて買えなかったから非常にありがたい。www.amazon.co.jp
普段からGitやGitHubは軽く使っているので、すらすらと読むことが出来た。
本の中でgit log -pやgit reflog、git rebaseなどの自分が知らないコマンドを簡単に説明してあった。普段Gitを使うのに困らない程度にしかGitコマンドを知らないので、少しずつでもGitコマンドを学ばなければいけないなと思った。また、GitHubにショートカットキーがあることもこの本で初めて知った。
Pull Requestを体験できるのも非常によかった。人生初Pull Requestを行った。
正直なところ、GitHubでIssueを書いたり、Pull Requestを送るのは自分にとってはまだまだ非常に敷居の高いことのように思う。これから少しずつ慣れていければとこの本を読んで思った。
RecyclerViewとCardViewを使ってみた。
Androidの開発をしたばかりで、わからないことが多い。今回はRecyclerViewとCardViewについて少しだけ学んだ。
Getting Started With RecyclerView and CardView on Android - Tuts+ Code Tutorial
少し古い記事だけど、このサイトのコードを写経してRecyclerViewとCardViewの使い方をなんとなく学んだ。
このサイトでは、簡単なプロフィールリストを作成していたので、それを真似てみた。
リストを作成することは出来たので、次はItemをタッチした時に、各プロフィールの詳細用のActivityを開くようにしようと思う。
コードを書いて学ぶことは大事だなと改めて感じた。