woshidan's blog

あいとゆうきとITと、とっておきの話。

mixi Android Training 第一回分メモ

補欠から繰り上がれたので行きました。目次を見たら分かる通り、自分用です。

内容

自分用メモ

  • 予習分
    • 前書き
      • Android-OSについて
      • プロジェクトの作成(Android Studio)
        • プロジェクトの構成について
        • srcディレクトリ
        • resディレクトリ
      • Androidの基礎知識
      • アプリのレイアウト作成

実際の授業について知りたい人はここから。

  • 授業分
    • アプリのレイアウト作成
      • dp(density-indeoendent pixels)
      • sp(scale-independent pixels)
      • Gravity
      • レイアウトを作成する
        • LinearLayout
        • RelativeLayout
        • FrameLayout
        • ScrollView
    • 授業中のgitterから
      • XML名前空間の簡単な説明
      • layout_weightの時に0dpとするのはなぜ
      • 便利なリンク集
    • 演習と課題について
      • FrameLayoutの演習メモ
      • 課題4について
        • 分割線
        • 要素間の余白
        • 一番下の段の3つのボタンの配置について
        • TextViewのandroid:drawableLeft, android:drawableTopで出した画像の位置調整
      • FrameLayoutの演習について
    • 授業の様子について

予習分

今回の範囲とは特に関係なかったのですが、モジュールディレクトリがどこかとかがよく分からなくて漠然と不安になったので、前段も読みました。

Android-OSについて

アーキテクチャ

Android OSはGoogleが開発している携帯用のOSです(iOSAppleが開発しているデバイス全般用のOS)。

アプリケーション、アプリケーションフレームワーク、ライブラリ、Androidランタイム、Linux カーネルのレイヤーに分かれていて、 Androidアプリを開発する時は、おもにアプリケーションフレームワークのレイヤーのコードを書いて、アプリケーション層のプログラムを開発することになります。

Dalvik VM

AndroidJavaです。実はScalaなんかも使えます。Dalvik VMはメモリ消費が少ないJavaと説明されることが多いですが、互換性が無い部分もあります。

たとえば、 JavaVM(Sun社製)がスタックマシンで、DalvikVMはレジスタマシン(特殊性)だったりするそうです。

それより、Androidでは、SunJavaと比べてもう一段階処理を施して、クラスファイルをDalvikVMで動作可能なようにするのですが、このときに生成されるファイルがdexファイルであるということを認識しておいた方が良いと思いました。

バグの原因が分からなくてあれこれ試してるうちに必要なファイルを消さないように、という意味で(棒)。

バージョン

バージョンごとにAPIが異なるので注意します。 プロジェクトを作成するとき、マニフェストファイルに対応するうちで一番古いバージョンと一番新しいバージョンを指定しておくと、対応するバージョンでは使われていないAPIを書いたときフレームワーク側の機能としてエラーや警告をはいてくれます。

プロジェクトの作成

プロジェクトの構成について

http://mixi-inc.github.io/AndroidTraining/introductions/1.03.create-project-for-android-studio.html

.idea ディレクトリにプロジェクトの設定ファイルが入っていて、 Moduleディレクトリがアプリで使うファイル群が入っています。 Moduleディレクトリの名前はプロジェクト作成時のModule nameという項目で決定します。

srcディレクトリ

ActivityクラスであったりViewクラスであったり、アプリケーションで使うクラス群の定義ファイルが入っています。

resディレクトリ

レイアウトファイルや定型文、画像等の各種リソースが格納されています。リソースの種類によって命名規則が決まっていたりします。

プロジェクトの作成

Application Nameはアプリの名前で、Module Nameはモジュールディレクトリの名前です。 Package Name は、アプリ固有の名前空間Google Play Storeでアプリの識別子として利用。 Proect location 作成するプロジェクトの配置場所

バージョンのところで書いていた仕組みとして、 アプリがサポートする最低バージョンの指定を Minumin Required SDK, Compile Withで動作させる最高バージョンを指定します。

Gradleのビルドシステム

http://mixi-inc.github.io/AndroidTraining/introductions/1.05.how-to-build-for-gradle.html 外部のライブラリを読み込みたいときにまた読もうと思いました。

アプリのレイアウト作成について

実際作業するときに忘れていたので、気になったことの確認

講義そのものとは関係ないです。

アクティビティで利用されるレイアウトファイルを変えるときは、 アクティビティのクラス内で

setContentView(R.layout.activity_main);

のR.layout.xxxx(レイアウトファイル名が入る)を変更します。

講義資料の例を自分で手打ちで確認してたときに同じファイルを書き換えるのだと見比べたりするのが面倒くさかったので。

レイアウトファイルだけ余分に作っていくのが微妙な場合は、 アクティビティとレイアウトファイルをセットで新しく作成して(こっちが普通な気がします)、マニフェストファイルをいじって起動時のアクティビティを変える方法もあるので、少し確認しておきます。

この場合はAndroidManifest.xml

<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.MAIN" />

という要素が中に入っているActibity要素のandroid:name属性を".起動時に表示させたいActivityのクラス名"に変更します。

とここまで書いて気づいたのですが、XMLを書き換えたら右側にレイアウトが表示されるので、 res/layout以下に新しくxmlだけ追加していけばよかったですし、 そもそもそれ用のリポジトリが用意されているのでcloneしてくればよかったです。

あと、レイアウトファイルの

tools:context=".MainActivity"

は、MainActivityというアクティビティに設定されているメニューや何もない部分の背景色の埋め方といった設定をこれから書くレイアウトファイルで引き継ぐよ、という意味です。 デフォルトでは対応しているアクティビティに設定されている設定を引き継ぐようになっているのでそのままでいいと思います(Androidよく知りませんが)。

意味が分からなくてもどうせ次回が次次回あたりでやるような気がしますのでとりあえずファイルを直に書き換えようと、意味が分からず書き換えようと、今回はレイアウトが上手く書ければいいと思います。

以下は、授業内容と自分のメモ。

アプリのレイアウト作成について

dp(density-independent pixels) 密度非依存のピクセル

pxを直接指定して使うと、解像度の大きい画面では小さな画像として、解像度の小さな画面では大きな画像として表示されますが、dpを使用すると、画面の解像度に対するサイズが一定となり、大きい画面では画面に見合う大きな画像として、小さな画面では画面に見合う小さな画像として表示されます。

実際の画面上でのpx値の計算法は px = dp * (dpi/160) です。

sp(scale-independent pixels) スケール非依存のピクセル

dpとは逆に、小さな画面では小さく、大きな画面では大きく、あるいは、小さな画面では大きくというふうに、画面サイズに寄って意図せずサイズが変わったら困る部品もあります。
たとえば、小さい画面に合わせて文字が一定サイズ以下になったら読めませんし、タブレットの画面サイズにあわせて拡大されても読みにくいです。
そういう、デバイスの画面のスケールとは関係無しに一定の大きさで表示されて欲しい部品にはspを使います。

Gravity

Gravityはlayout_gravityが自分の位置を、gravityが内部の要素の位置を決めます。
layout_gravityとgravityの区別について、まあ書きゃすぐ分かるんですが、Layout要素に書くと長々しいから、Layout要素に入れる中身の要素にかいて、中の要素の位置を直接いじる方って覚えてます(いい加減)。

TextViewは内部に自分以外の要素を含みませんが、gravity="right"と指定するとテキストが右寄せになります。

レイアウトを作成する

レイアウト=~~Layout要素のことで、ListViewはウィジェットの類いだと勝手に思ってましたが、レイアウトなんですね。

LinearLayout

LinearLayoutのorientationが未定義の場合は、horizontal
layout_weightでの一列にならんだ要素の幅の比率を決められます。
layout_weightを使う時はlayout_width="0dp"とします。

RelativeLayout

android:idはButtonなどのレイアウトファイルに書いた要素に割り振るidです。
RelativeLayoutのtoRightOf...だったり、alignBottomだったりの指定に使う以外に、 イベントリスナの登録に使ったとおもいます。

layout_centerHorizontal(横方向)
layout_centerVertical(縦方向)
layout_centerInParent

... 親となるViewの中央に配置します。

alignParentLeft
alignParentRight
alignParentBottom
alignParentTop

... 親となるViewの端に自分の端が一致するように配置します。

alginRight = "@+id/b"
alginLeft = "@+id/b"
alginTop = "@+id/b"
alginBottom = "@+id/b"

... 指定したidを持つ要素の端と自分の端が一致するように配置します

alignBaseline = "@+id/b"

... 指定したidのベースラインにあわせて配置します

layout_above = "@+id/b"
layout_below = "@+id/b"
layout_toLeftOf = "@+id/b"
layout_toRightOf = "@+id/b"

... 上から順に、指定したidの上側、下側、左側、右側に配置します

FrameLayout

XML内で上に書いた順から下側に配置されます。 ここだけ元の資料でも記述がかなり少ないので、「書いてる人が途中でやる気なくなっちゃったんですか(笑)」とか言われてました。

ScrollView

画面にレイアウトが収まらない場合、収まらない分をスクロールして表示するために使う ScrollViewの中に直接的に入れていい要素の数は1つ。 たとえばTextView要素を二つ入れたい場合は、二つのTextView要素をLinearLayout要素でくるんでからScrollViewに入れます。

駄目な例

<ScrollView>
  <TextView />
  <TextView />
</ScrollView>

いい例

<ScrollView>
  <LinearLayout>
    <TextView />
    <TextView />
  </LinearLayout>
</ScrollView>

演習と課題について

FrameLayoutの演習メモ

layout_gravityは|で複数方向を指定できる

cf.右上寄せ

layout_gravity="top|right"

課題4について

分割線
頑張って書いたもの

res/drawable以下に

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="1dp"
    android:shape="rectangle"
    android:layout_height="100dp"> <!-- ここの長さは適当。縦の長さはlayout_alignBottomとかで合わせる -->
    <solid android:color="#111111"/>
</shape>

という黒い四角形を用意して、これをImageViewのsrc属性に指定して呼び出す。

解答
<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:layout_below="@+id/ProfileImageContainer"
    android:background="#393939"/>

幅1dpの黒背景のViewを使用。

要素間の余白

解答では機能を持った要素のmarginやpaddingでなくて透明なView要素を使用。

一番下の段の3つのボタンの配置について

LinearLayoutのlayout_weightを0:1:0で指定していたが、解答ではRelativeLayoutで左右の要素(幅固定)を入れてから真ん中の要素を入れてありました。
なるほど。。

TextViewのandroid:drawableLeft, android:drawableTopで出した画像の位置調整

分からなかったのですが、解答見たら画像の位置調整をTextViewのgravityやlayout_CenterInParentなどを使ってやってました。

FrameLayoutの演習について

FrameLayoutは資料の記述が少なくてどうかと思ったのですが、FrameLayoutの演習は特に問題ありませんでした。

授業中のgitterから

XML名前空間の簡単な説明

Androidのレイアウトファイルの最初の要素にある

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"

あたりは何なのか、という話。

リンク先を元にちょっと自分の言葉でまとめました。

XMLを記述するときは本来独自のマークアップ言語(語彙)を自由に設計できますが、多くの人が利用する場合は、標準的な語彙は共有する方が開発効率がよいです。 ただ、標準的な語彙、というのは、いくつかの言語で違う意味で用いられていることが用意に想像できます。

たとえば、titleがある言語は書物のタイトルだったり、別の言語では作者の肩書きだったり。

同じ語を使って意味が違っては困るので、XMLの言語(語彙)を一意に指定するための仕組みであるXML名前空間[XMLNS]を利用します。XMLNSでは、語彙とURIを組み合わせることで、複数の語彙を混在することも出来ます。

具体的には、使用したい要素でxmlns:語彙名という属性を用意して、語彙の設定ファイルが保存されているアドレスを値に指定。その要素の子要素で、語彙名:語と指定することで語彙が一意な状態で利用できます。

たとえば、bookとprofという二種類のXMLの語彙を1つのXMLの要素中で使う場合は、

<body xmlns:book="http://example.com/ns/book/"
xmlns:prof="http://example.com/ns/profile/">
 ...
  <book:title>ユニバーサルHTML/XHTML</book:title>   (1)
  ...
  <prof:title>コントラバス奏者</prof:title>                 (2)
   ...
</body>

のようにします。

以上から、

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"

の部分はAndroid用の語彙をandroid:, tools:という接頭辞をつけて使用する、という設定っぽいです。 これを抜くと、 android:layout_ ... などレイアウトファイル中の語彙が途端に赤くなるので、先頭の要素の属性をむやみに抜いてはいけません、というお話。

layout_weightの時に0dpと明示することで計算コストをはぶけるから layout_width=“0dp"

たとえば、1つの要素をlayout_width="wrap_content",layout_weight="0"にしてもう1つの要素をlayout_width="wrap_content",layout_weight="1"にした場合。
この場合だと、前者と後者でそれぞれその要素の内容を包む分だけ幅を取った後、前者の幅を記録しながら、後者は余白を全取りするように幅を再計算する。
layout_width="0dp"にしておくと計算しなくていいから、一回目の計算は要らない、という話で合っているのでしょうか。

素直に警告には従いましょうという話ですが。

便利なリンク集

特に後で見たいものを貼る。

Android Studioで覚えておくと便利なこと - Qiita

Android Studio ショートカットキーリスト for Mac - Qiita

授業の様子について

  • 参加者側はあんまり呟く余裕がなさそうな感じでした
    • でもsushiは呟く
    • いまどこの章見てる、とかでいいから気軽に実況すれば良いのに()と思います
    • 今回の講義内容はmixiの社内講義(4時間)でも終わらない内容なのだとか
    • 次回までの課題は、以下URLの課題までだと思います

アプリのレイアウト作成 - mixi-inc/AndroidTraining

  • 授業中にリポジトリのクローンを始めてなかなか演習が始められない人が結構
    • mixiのAndroidTrainingの課題が入っているリポジトリは全部の回の課題が入っているため、重いみたいです。なので、どの回から参加の場合でも事前に課題用リポジトリをcloneだけしておくと安心かも
  • 次の、Gradleのダウンロードで時間がかかっている人もちらほら
    • Gradleもそれなりに重いので、課題をやらなくても何題分か表示まで進めておくと安心かも
    • 公式でも1個目の課題の表示が推奨されてました