2016年に見たアニメ
去年も書いたので今年の分も書いて振り返る。読みが五十音順になるよう並べていますが、そうなっていないところがもしあればそれは間違いです。
冬クール
アクティヴレイドとか昭和元禄落語心中は放送が終わった頃にようやく録画したやつを一気に見たけど素晴らしかった。他にもグリムガルとかGATE、デュラララ、僕だけがいない街、だがしかし、亜人、暗殺教室、しょこめざ、ディメンションW、ルパン、などなど好きな感じのやつが多かったクールだったと思う。
- アクティヴレイド -機動強襲室第八係-
- 亜人
- 暗殺教室(第2期)
- おしえて! ギャル子ちゃん(USAT)
- 彼女と彼女の猫 -Everything Flows-(USAT)
- GATE 自衛隊 彼の地にて、斯く戦えり 炎龍編
- 少女たちは荒野を目指す
- 昭和元禄落語心中
- 石膏ボーイズ(USAT)
- だがしかし
- 旅街レイトショー(USAT)
- ディメンションW
- デュラララ!!×2 結
- 灰と幻想のグリムガル
- ハルチカ ~ハルタとチカは青春する~
- ブブキ・ブランキ
- 僕だけがいない街
- 無彩限のファントム・ワールド
- ラクエンロジック
- ルパン三世 イタリアン・ゲーム
- WORKING!!! 第14話「ロード・オブ・ザ・小鳥遊」
春クール
カバネリ、ヒロアカ、クロムクロ、ジョジョ、うしおととらなど熱い展開の話が多かったかな。クロムクロは自分のよく知っている風景がアニメに出てくるのをみるとなんとなく嬉しい感じになってよかった。忍殺はニコニコで1話を見たとき全然理解できなくてそれ以降見てなかったけど、今回改めて見たら最高にいかれててよかった。
- うしおととら(第2期)
- 宇宙パトロールルル子(USAT)
- 影鰐 - KAGEWANI - 承(USAT)
- キズナイーバー
- くまみこ
- クロムクロ
- 甲鉄城のカバネリ
- 坂本ですが?
- 三者三葉
- ジョジョの奇妙な冒険 ダイヤモンドは砕けない
- ジョーカー・ゲーム
- ニンジャスレイヤー フロムアニメイシヨン TVシリーズ(スペシャル・エディシヨン版)
- ハイスクール・フリート
- ばくおん!!
- 文豪ストレイドッグス
- 僕のヒーローアカデミア
- 迷家-マヨイガ-
夏クール
アクティブレイドが王道を突き進んで堂々と終わったのが最高に良かった。アルデラミンは二期を早く見たいなあ。ぞい!とかReLIFEは今の自分に鋭利に刺さる感じの話しで個人的にはつらかったけどおもしろかった。斉木楠雄のΨ難は純度の高い良質な神谷浩史成分を摂取できるアニメだった。
- アクティヴレイド -機動強襲室第八係- 2nd
- 甘々と稲妻
- あまんちゅ!
- この美術部には問題がある!
- 斉木楠雄のΨ難
- タブー・タトゥー
- ダンガンロンパ3 -The End of 希望ヶ峰学園- 絶望編
- ダンガンロンパ3 -The End of 希望ヶ峰学園- 未来編
- 91Days
- NEW GAME!
- ねじ巻き精霊戦記 天鏡のアルデラミン
- バッテリー
- ベルセルク
- ラブライブ! サンシャイン!!
- Rewrite
- ReLIFE
秋クール
ユーフォが3話ごとぐらいに神回をもってきてすごかったし黒沢ともよの演技もすごかった。イゼッタ、ドリフ、オカン、SBR#、舟を編む、ブレイブウィッチーズあたりもすごく好きで、いっせいに終わってしまうのが寂しくもある。わたモテは完全に女性向けだと思うんだけど、振り切れた小林ゆうとそれに付き合って振り切れる沢城みゆきを楽しめたのでよかった。
- 亜人(第2クール)
- うどんの国の金色毛鞠
- Occultic;Nine -オカルティック・ナイン-
- 終末のイゼッタ
- SHOW BY ROCK!!#
- WWW.WORKING!!
- ダンガンロンパ3 -The End of 希望ヶ峰学園- 希望編
- ドリフターズ
- 響け!ユーフォニアム2
- 舟を編む
- ブブキ・ブランキ 星の巨人
- ブレイブウィッチーズ
- 文豪ストレイドッグス セカンドシーズン
- 私がモテてどうすんだ
再放送枠
Web
最後に宮沢賢治の「星めぐりの歌」が流れて無事に涙腺崩壊した。
- planetarian ~ちいさなほしのゆめ~
劇場版枠
もっと見た気がしてたけど去年より2本多いぐらいだった。アニメ以外ではシン・ゴジラと聖の青春を見ているので例年よりは映画を見ていると思われる。どれも最高に面白かった。MJPは二期も見てみたい。
- 劇場版「艦これ」
- 君の名は。
- きんいろモザイク Pretty Days
- 聲の形
- この世界の片隅に
- 劇場版 響け!ユーフォニアム ~ 北宇治高校吹奏楽部へようこそ ~
- planetarian ~星の人~
- 劇場版マジェスティックプリンス
- 劇場版 ラストエグザイル ‐銀翼のファム‐ Over The Wishes
ImageSpanを使って画像をTextViewの中にいい感じに表示する
(これはAPI Level 25(Android 7.1.1)のNexus5XおよびAPI Level 23(Android6.0)のNexus5(エミュレータ)で確認した)
TextView
はsetCompoundDrawables(Drawable, Drawable, Drawable, Drawable)
を使うと文字領域の上下左右に一つずつDrawable
を置くことができるが、文章の中に画像を置いたり、例えば右の領域にDrawable
を二つ並べて置くということはできない。そんな時の代替手段の一つにImageSpan
がある。HTMLのimg
タグに相当するものだろうか。
https://developer.android.com/reference/android/text/style/ImageSpan.htmldeveloper.android.com
これを使って、
RT by [アイコン画像] @screen_name
とか、
ユーザ名 @screen_name [認証マーク] [鍵マーク]
のように文字と画像とを一列に並べようとしていたところ、画像の底辺をどこに合わせるか指定する引数にALIGN_BOTTOM
を選ぶ(デフォルト)と上の方に不思議な隙間ができてしまったのでどんな処理をしているのか見てみることにした。軽くぐぐってみると高さが合わない問題はすでに認識されている様子(たとえば、複数行のTextViewでImageSpanが下付きに描画される事象を回避する - Qiita)。この情報にならってDynamicDrawableSpan#draw()
をオーバライドして解決を試みようとしたのだが、問題はどうもDynamicDrawableSpan#getSize()
の方にあるのではないかという気がした。その理由を次から説明する。
DynamicDrawableSpan#draw()
の引数の意味
DynamicDrawableSpan | Android Developersをみると引数についての説明がある。ここで重要なのは次の三つ。
top
: 行(Canvas
)の上辺(ふつう0?)y
: ベースラインbottom
: 行(Canvas
)の底辺
DynamicDrawableSpan#getSize()
では何をやっているのか
Cross Reference: /frameworks/base/core/java/android/text/style/DynamicDrawableSpan.java
(2016/12/19 12:28 追記)親クラスgetSize()
やdraw()
の説明がある:Cross Reference: /frameworks/base/core/java/android/text/style/ReplacementSpan.java
getSize()
の戻り値はint
なのだが、これはdraw()
で描こうとするものの幅がどれだけかという意味。なのでgetDrawable().getBounds().right
を返せばよいだけのはずなのだが、ついでに引数であるPaint.FontMetricsInt
の中身を書き換えている。具体的には次に挙げる変数の値を書き換えているのだが、これはdraw()
で描こうとするものの高さ方向のデータになる。
top
: グリフの中で最も背の高い文字の、ベースラインから上側の距離(負の数)ascent
: 一つの文字で推奨されるベースラインから上側の距離(負の数)descent
: 一つの文字で推奨されるベースラインから下側の距離(正の数)bottom
: グリフの中で最も足が長い文字の、ベースラインより下側の距離(正の数)
ちなみにこの説明は、Paint.FontMetrics
の方にしか書いてない。top
やascent
が負の数である理由は、スクリーンの座標系が上から下に向かって大きくなっているためらしい。ここで設定した値に応じてdraw()
のtop
やy
やbottom
の値が決まるようである。
getSize()
の元の処理は、ベースラインから上側の距離をDrawable
の高さと等しくして、ベースラインから下の距離を0に設定している。その上でdraw()
ではbottom
にDrawable
の底辺を揃えて、ALIGN_BASELINE
の時にはさらにベースラインからdescent
の分だけ上に引きあげようという計算をしている。つまり、ベースラインの上側にDrawable
の高さ分のスペースを確保しているのに、それよりさらに低いbottom
の位置に底辺を合わせているので、ALIGN_BOTTOM
の時にはbottom
の分だけDrawable
の上に隙間ができるということである。その行の他の文字がベースラインの下側を使っているために、getSize()
で指定したbottom=0
が却下されてしまうのではないかと思われる。
上の隙間をなくすには
画像の領域をベースラインの上側にのみ確保しようとしているのがそもそもおかしいのではないか。そうしたいのはALIGN_BASELINE
を指定した時だけのはず。なので単純に次のようにしてみた。ポイントはDrawable
のベースラインをどこにするか。getCachedDrawable()
はprivate
メソッドなので再定義する必要がある。
(2016/12/21 22:37:paint.getFontMetrics()
を使って計算するよう修正)
@Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { final Rect bounds = getCachedDrawable().getBounds(); if (fm != null) { final Paint.FontMetrics fontMetrics = paint.getFontMetrics(); final int verticalAlignment = getVerticalAlignment(); if (verticalAlignment == ALIGN_BASELINE) { fm.ascent = -bounds.bottom; } else if (verticalAlignment == ALIGN_BOTTOM) { fm.ascent = (int) (bounds.bottom * fontMetrics.top / (-fontMetrics.top + fontMetrics.bottom)); } fm.descent = Math.max(bounds.bottom + fm.ascent, 0); fm.top = fm.ascent; fm.bottom = fm.descent; } return bounds.right; } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int baseline, int bottom, Paint paint) { final Drawable cachedDrawable = getCachedDrawable(); final int drawableHeight = cachedDrawable.getBounds().bottom; canvas.save(); int transY = top; if (getVerticalAlignment() == ALIGN_BASELINE) { transY = baseline - drawableHeight; } else if (getVerticalAlignment() == ALIGN_BOTTOM) { transY = bottom - drawableHeight; } canvas.translate(x, transY); cachedDrawable.draw(canvas); canvas.restore(); }
例に挙げた先のページでは、複数行のTextView
でline spacingを1.5に設定すると画像が下付き文字のようになってしまうという現象が確認されているが、これはdraw()
の引数であるbottom
が行間の高さも含んでいるためではないかと考えられる。Paint.FontMetricsInt
は行間の高さをleading
という変数名で持っている。このleading
の分だけ上に移動させてやることで意図した通りに表示できるのではないかと思われる。上のソースでいうと
transY = bottom - drawableHeight;
を
transY = bottom - drawableHeight - paint.getFontMetricsInt().leading;
にするという感じ。これは手元では確認していないので間違っているかもしれない。
今後の展望
中央揃えができたらいいなと思っている。一連のソースは[WIP] introduced RetweetUserView to replace RT user container by akihito104 · Pull Request #166 · akihito104/UdonRoad · GitHubに上がっており、そのうちマージされる予定。パッチ書いてAOSPに取り込まれるのが一番いいんだと思うんだけどいろんなケースに対応できるかどうかはちょっと自信がない。でもチャレンジしてみるのもいいのかな。
関係ありそうなissueとか
android - Align text around ImageSpan center vertical - Stack Overflow
Html.fromHtml()はカジュアルに使うものではない?
拙作のツイッタークライアントが、起動して3時間ほど放置しておくと全く動かなくなってしまうようになった。どこか触るとANRが出て落とせるので、その都度traces.txt
を見ると、いつもHtml.fromHtml()
を呼んでるところで止まっている様子。
内部ではパーサーオブジェクトのイニシャライズでnew char[2000]
をやっているところだった。
Cross Reference: /external/tagsoup/src/org/ccil/cowan/tagsoup/Parser.java
名前やコメントから察するにこの配列はHTMLのコメント部分を読み込む時に使うバッファのようなのだが、メンバ名で検索しても宣言の箇所しかヒットしない。可視性がprivate
なのでなんのためにあるのかわからなかった。
traceviewで見ると処理時間も結構かかるようだし、せいぜい1行のTextView
に使うには大げさなのかなと思ってなるべく呼ばないようにする工夫を入れた。固まってしまう原因はまだよくわからないので経過を見守ることにする。
(これはAndroid 6.0で確認した)