Android Studio - サンプルプロジェクトを読んでみる
MainActivity
ActionBarActivityを継承している。
ActionBarはAndroidアプリの上部についてるナビゲーションバーのこと。標準のサポートライブラリに含まれている。
android.support.v7.app | Android Developers
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()) .commit(); } }
Bundle savedInstanceState
とは、アプリ終了時の状態を保存しているもの。なのでこのif節では、初回起動時にどうするかという処理をしている。
(初回起動時だけじゃなくて、何か他の時にも入りそう/未確認)
getSupportFragmentManager()
は、現在のActivityに関連するFragmentManagerを取得するもの。
FragmentActivity | Android Developers
そこで取得したMangaerを使って、トランザクションを開始し、PlaceHolderFragmentというフラグメントをR.id.container
というidで定義されたlayoutに紐付ける。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" tools:ignore="MergeRootFrame" />
layoutファイルのtools:context
とはなんぞや??
xml - What's "tools:context" in Android layout files? - Stack Overflow
StackOverflowによると、UIエディタがレイアウトをレンダリングするときに使うActivityということで…ここと連動しているみたい↓
ActivityだけでなくFragmentを指定することも出来る。
fragment_main.xml
tools:context=".MainActivity$PlaceholderFragment
tools:ignore
ではAndroid Lintを部分的に無視する設定をしている。
AndroidLintについての説明はこちらが詳しい。
Android Lint の利用方法を記載 | Bescottee
lintとはそもそも湿布に使われているようなふわふわ起毛した布とか綿くずのことを言うらしい。で、C言語には
というものがある。free lint(糸くずが出ない)って言葉から転じて、僅かな綻びもないコード…という意味になったかは知らないけど(すみません思いつきで言っています)、とにかくlintはちょっとしたミスを指摘してくれるやつです。例えばhtml lintなら閉じタグが足りないよ!とか言ってくれます。
で、Android Lintも同様に細かなチェックをしてくれるようで、これはADT16(2011年12月版)から追加された機能のようです。
lintが何をチェックしているかは以下で見れます。
http://tools.android.com/tips/lint-checks
目についたものを抜粋してみると…
- NewApi: Finds API accesses to APIs that are not supported in all targeted API versions
- ShowToast: Looks for code creating a Toast but forgetting to call show() on it
- Toast作ってるけどshowしていない(確かにこれ書き忘れやすいよね…)
- Deprecated: Looks for usages of deprecated layouts, attributes, and so on.
- 非推奨なレイアウトとか属性とかを使っている
などなど。色々ありますね。
さて、知りたかったMergeRootFrameはどんなやつなのかというと
MergeRootFrame
Summary: Checks whether a root <FrameLayout> can be replaced with a <merge> tag
Priority: 4 / 10 Severity: Warning Category: Performance
If a <FrameLayout> is the root of a layout and does not provide background or padding etc, it can often be replaced with atag which is slightly more efficient. Note that this depends on context, so make sure you understand how the <merge> tag works before proceeding.
More information: Android Layout Tricks #3: Optimize by merging | Android Developers Blog <<
合ってるか分からないけど訳してみると…
ルートのFrameLayoutが<merge>タグで置換されていいかどうかチェックする。 もしFrameLayoutがレイアウトのルートで、背景やpaddingを提供しないなら、mergeタグに置換することで少し効率的にできます。これは状況次第なので、mergeタグがどのような働きをするのかちゃんと理解してくださいね。
…という感じ?
Android Layout Tricks #3: Optimize by merging | Android Developers Blog
mergeタグを使うとレイアウトの階層が深くなるのを抑えることができます。
hierarchy viewerで実際に確認してみようと思ったのですが、Android Studioのどこにあるのか見つけられない…orz
探しまわっていたら、棚ぼた的に、Preferences->Inspections->Android LintでどのLintを検知してどれは無視するのか、自由に設定できることが分かりました。
話を大きく戻して、PlaceholderFragmentですが、MainActivityの下の方に定義されていました。
/** * A placeholder fragment containing a simple view. */ public static class PlaceholderFragment extends Fragment { public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); return rootView; } }
Fragmentはサポートライブラリ(v4)で定義されている機能で、Activityとレイアウトの間を取り持つものというイメージで…いいのかな…。
Activityで直接レイアウトとロジックを管理すると、1つの画面に複数の機能が含まれるときに大変。例えばfbの左からスライドして出てくるメニュー画面と、ヘッダーと、コンテンツ部分なんかはそれぞれのレイアウトにそれぞれをロジックをくっつける感じで扱えた方が便利です。特にAndroidの場合画面が大きい端末が多かったりするので、横レイアウトの時には左のメニューを出しっぱなしにしたい、とかいう場合に、ロジックは同じものを使い回せるのでFragmentは便利です。
……ってことがこの本に載ってました。もっと正しく分かりやすく書いてあるので詳しくはこちらを参照で。
Android UI Cookbook for 4.0 ICS(Ice Cream Sandwich)アプリ開発術
- 作者: あんざいゆき
- 出版社/メーカー: インプレスジャパン
- 発売日: 2012/03/16
- メディア: 単行本(ソフトカバー)
- 購入: 2人 クリック: 47回
- この商品を含むブログ (18件) を見る
Fragmentの中にもライフサイクルがあります。
Fragmentを動的に変化させる « Tech Booster
onCreateViewはFragmentに関連付けるViewを返します。
View rootView = inflater.inflate(R.layout.fragment_main, container, false); return rootView;
ここでcontainer
にはactivity_main.xmlで定義されているFrameLayout(つまりActivity全体の大枠のレイアウト)が入ります。
http://y-anz-m.blogspot.jp/2012/04/android-viewgroup.html
なので、rootView
をデバッグして見てみると、android.widget.RelativeLayout
(fragment_main.xmlで定義されている大枠)になっています。
要は、第三引数がtrueなら、第二引数を返し、第三引数がfalseなら第一引数のルートレイアウトを返す。ただし、第二引数がnullの場合には第一引数のルートレイアウトを返す。…のかな…。
ちょっとこの辺りは要勉強という感じがします。
一旦ここまで。