Android StudioのActivityTemplate全部試してみた!(2/2)
前回に引き続き、AndroidStudioのActivityのサンプルを試してみます。 残り6個!
目次
- LoginActivity
- Master/Detail Flow
- TabbedActivity
- SettingsActivity
- ScrollingActivity
- NavigationDrawer
LoginActivity
特徴
- 一般的なログインフォーム
- 補完機能などUIが充実
Source
xml
<!-- プログレスバー --> <ProgressBar android:id="@+id/login_progress" style="?android:attr/progressBarStyleLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:visibility="gone" />
<!-- メールアドレスの補完機能がついたTextView --> <AutoCompleteTextView android:id="@+id/email" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/prompt_email" android:inputType="textEmailAddress" android:maxLines="1" android:singleLine="true" />
自動補完用のTextViewなんてあったんですね。
Activity
長いのでメソッド名だけ、
- permission処理
- mayRequestContacts()
- onRequestPermissionResult(Int, Array
, IntArray)
- 連絡帳アクセス
- onCreateLoader(Int, Bundle?)
- onLoadFinished(Loader>Cursor>, Cursor)
- textViewに補完
- addEmailsToAutoComplete(List
)
- addEmailsToAutoComplete(List
- 通信処理
- inner class UserLoginTask
- プログレスダイアログ
- showProgress(Boolean)
機能だけでなく、UX的な面でも参考になります……!
Master/Detail Flow
特徴
Source
基本は一般的なActivityとFragmentです。特徴的なのは、出し分けのロジックですね。
今回はこれを2つのitem_list.xml
の呼び分けで実現しています。app/src/main/res/layout
にあるものが呼ばれていればスマホサイズ、app/src/main/res/layout-w900dp
のものが呼ばれていればタブレットサイズとなります。
Activity
if (item_detail_container != null) { // The detail container view will be present only in the // large-screen layouts (res/values-w900dp). // If this view is present, then the // activity should be in two-pane mode. twoPane = true }
onClickListener = View.OnClickListener { v -> val item = v.tag as DummyContent.DummyItem // タブレットかどうか if (twoPane) { val fragment = ItemDetailFragment().apply { arguments = Bundle().apply { putString(ItemDetailFragment.ARG_ITEM_ID, item.id) } } parentActivity.supportFragmentManager .beginTransaction() .replace(R.id.item_detail_container, fragment) .commit() } else { val intent = Intent(v.context, ItemDetailActivity::class.java).apply { putExtra(ItemDetailFragment.ARG_ITEM_ID, item.id) } v.context.startActivity(intent) } }
TabbedActivity
特徴
3種類のスタイルがあります。
- Swipe Views
- Action Bar Tabs
- Action Bar Spinner
が、、、全体的に上手くいきませんでした。
SwipeViewsはデザインが違い、その他はそもそもビルドが出来ませんでした。
AndroidStudioのバージョンにもよるのでしょうが、別途自分で書いてみます。
SettingsActivity
特徴
アプリの設定画面を生成してくれます。
アプリ内で完結したいものは、OSの設定画面へと遷移してくれます。
Source
AppCompatPreferenceAcrivityでPreferenceごとにFragmentを定義しています。
@TargetApi(Build.VERSION_CODES.HONEYCOMB) class GeneralPreferenceFragment : PreferenceFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) addPreferencesFromResource(R.xml.pref_general) setHasOptionsMenu(true) // Bind the summaries of EditText/List/Dialog/Ringtone preferences // to their values. When their values change, their summaries are // updated to reflect the new value, per the Android Design // guidelines. bindPreferenceSummaryToValue(findPreference("example_text")) bindPreferenceSummaryToValue(findPreference("example_list")) } override fun onOptionsItemSelected(item: MenuItem): Boolean { val id = item.itemId if (id == android.R.id.home) { startActivity(Intent(activity, SettingsActivity::class.java)) return true } return super.onOptionsItemSelected(item) } }
の繰り返しです。
また、xml/pref_xxx
でpreferenceごとの画面を定義しています。
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to dismiss it. --> <!-- NOTE: ListPreference's summary should be set to its value by the activity code. --> <ListPreference android:defaultValue="180" android:entries="@array/pref_sync_frequency_titles" android:entryValues="@array/pref_sync_frequency_values" android:key="sync_frequency" android:negativeButtonText="@null" android:positiveButtonText="@null" android:title="@string/pref_title_sync_frequency" /> <!-- This preference simply launches an intent when selected. Use this UI sparingly, per design guidelines. --> <Preference android:title="@string/pref_title_system_sync_settings"> <intent android:action="android.settings.SYNC_SETTINGS" /> </Preference> </PreferenceScreen>
こうやって使うんですね。
ScrollingActivity
特徴
- CollapsingToolbarLayoutの中に配置したAppBarの大きさが可変になる
Source
そのままじゃ上手く表示されなかったのでちょっと修正……
以前紹介した本を参考にしました。
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="180dp" android:elevation="10dp"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/toolbarLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/colorPrimary" app:layout_collapseMode="pin" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ScrollingActivity" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mar[f:id:t-miliya612:20180510205238p:plain]gin="@dimen/text_margin" android:text="@string/large_text" /> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout>
app:layout_behavior="@string/appbar_scrolling_view_behavior"
を忘れるとコンテントの文字が被ってしまうので要注意です。
NavigationDrawer
特徴
- 左側から出てくるタイプのナビゲーション
Source
設定は結構簡単でした。
Activity
val toggle = ActionBarDrawerToggle( this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) drawer_layout.addDrawerListener(toggle) toggle.syncState() nav_view.setNavigationItemSelectedListener(this)
activity_navigation_drawer.xml
... <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_navigation_drawer" app:menu="@menu/activity_navigation_drawer_drawer" /> ...
layout/nav_header_navigation_drawer.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="@dimen/nav_header_height" android:background="@drawable/side_nav_bar" android:gravity="bottom" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:theme="@style/ThemeOverlay.AppCompat.Dark"> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/nav_header_desc" android:paddingTop="@dimen/nav_header_vertical_spacing" app:srcCompat="@mipmap/ic_launcher_round" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="@dimen/nav_header_vertical_spacing" android:text="@string/nav_header_title" android:textAppearance="@style/TextAppearance.AppCompat.Body1" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/nav_header_subtitle" /> </LinearLayout>
menu/activity_navigation_drawer_drawer.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:showIn="navigation_view"> <group android:checkableBehavior="single"> <item android:id="@+id/nav_camera" android:icon="@drawable/ic_menu_camera" android:title="Import" /> <item android:id="@+id/nav_gallery" android:icon="@drawable/ic_menu_gallery" android:title="Gallery" /> <item android:id="@+id/nav_slideshow" android:icon="@drawable/ic_menu_slideshow" android:title="Slideshow" /> <item android:id="@+id/nav_manage" android:icon="@drawable/ic_menu_manage" android:title="Tools" /> </group> <item android:title="Communicate"> <menu> <item android:id="@+id/nav_share" android:icon="@drawable/ic_menu_share" android:title="Share" /> <item android:id="@+id/nav_send" android:icon="@drawable/ic_menu_send" android:title="Send" /> </menu> </item> </menu>
まとめ
全体的に学習材料として面白かったです。ただ、Tab系のActivityは謎でした……結構使いそうな気がするんだけどなぁ。
初めて実装する際には、手直しのことも考えるとEmptyActivityで頑張った方がよさそうですね。
そして、 初めから全部で2記事って決めると大変つらいことになる という学びを得ました。以上です。