Toolbar
Toolbarを使ってonOptionsItemSelected()をactivity毎に記載する方法と、Fragmentを使ってonOptionsItemSelected()する方法について。
Fragment不使用
Toolbar表示まで
androidx
manifest build.gradle dependencies implementationは、androidxのappcompatであることを確認ね
dependencies{
...
implementation 'androidx.appcompat:appcompat:1.1.0'
...
}
AppCompatActivityを拡張
public class MyActivity extends AppCompatActivity{
}
manifestでNoActionBarテーマを設定
以下はandroidx未満の説明。androidxでの扱いが不明だったので、一応呪文として書いておく。
manifestの要素でappcompatのNoActionBarテーマの何れかを使用するように設定すると、ネイティブのActionBarでアプリバーが使えなる、とリファレンスに書いてある。
<application
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
Toolbarをレイアウトに追加
ConstraintLayoutだとToolbarをparentに関連付けないとエラーになるので注意
<androidx.appcompat.widget.Toolbar
android:id="@+id/myToolbar"
android:layout_width ="match_parent"
android:layout_height="?attr/actionBarSize"
android:background ="?attr/colorPrimary"
android:elevation ="4dp"
android:theme ="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@sytle/ThemeOverlay.AppCompat.Light"/>
// attr 適用してるテーマに定義されてる値を参照
// elevation UIの高さ。影をつける
// popup ポップアップ
setSupportActionBar()にToolbarを渡す(ToolBar表示)
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(SavedInstanceState);
setContentView(R.layout.activity);
Toolbar myToolbar = (Toolbar) findViewById(R.id.myToolbar);
setSupportActionBar(myToolbar);
}
// setSupportActionBar AppCompatActivityのmethod
ToolBarアクションの追加
アプリバーの余白にアクションを表示させ、余白がなくなればオーバーフローメニューに格納する。オーバーフローメニューのみを使うように設定できる。
menu.xmlの作成
res/menu/menu.xml
res直下にmenuディレクトリを作成し、menu.xmlを作成して配置する。
<menu xmlns:andoid="http://schemas.android.com/apk/res/android">
<!-- 以下は、"お好みのアクション"の登録 -->
<!-- OverFlowMenuに余白があれば、action Buttonを表示 -->
<item
android:id="@+id/action_favorite"
android:icon="drawable/ic_favorite"
android:title="お好み"
app:showAsAction="ifRoom"/>
<!-- 下はOverFlowMenuに登録 -->
<item
android:id="@+id/action_settings"
android:title="アクション"
app:showAsAction="never"/>
</menu>
// showAsAction
// action ItemをAppBarに表示する、タイミング、方法を指定
// ifRoon スペースがある限りAppBar内に表示
// スペースがないとき、orderInCategory値が小さいアイテムからactionとして表示される
// 残りはOverFlowMenuに格納
// never AppBar内には配置せず、OverFlowMenu内にアイテムをリスト表示
// その他 withText / always / collapseActionView
Action追加
AplBarのアイテムを選択する -> Activityの onOptionsItemSelected() コールバックメソッドに、MenuItemオブジェクトを渡す -> 選択してアイテムを表示
onOptionsItemSelected()の実装では、MenuItem.getItemId()メソッドを呼び出して、選択アイテムを判別する。返されるIDはandroid:id属性の値。
@Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.menu,menu);
// res の menuディレクトリのmenu.xml を ,menuに設定してインフレートする
return true;
}
@Override
public boolean onOptonsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.action_settings:
return true;
case R.id.action_favorite:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
アップアクション(MainActivityに戻るアクション)
MainActivity以外のActivityのアプリバーに、アップボタンを表示させる。ユーザはアップボタンを選択するだけでMainActivityに移動できる。
manifestで親Activityを宣言し、AppBarのアップボタンを有効にする。
Manifest 親子Activityを宣言
android:parentActivityName属性はAndroid4.1(API16)で導入。
旧バージョンのAndroidディバイスでするならの名前と値のペアを定義する。ここで、Nameは、"android.support.PARENT_ACTIVITY"、値は親ActivityのName。
以下は、MainActivityと子Activityで親子関係を指定する例。
<application ...>
...
<!-- MainActicity(親Activityを持たない) -->
<activity
android:name="com.oldcat.sample.MainActivity"
...>
</activity>
<!-- MainActivityの子 -->
<activity
android:name="com.oldcat.sample.ChildActivity"
android:label="ChildTitle"
android:parentActivityName="com.oldcat.sample.MainActivity"
>
<!-- support4.0以下では <meta-data>で親子を指定する -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.oldcat.sample.MainActivity"
/>
</activity>
</application>
アップボタンを有効にする
getSupportActinBar() で AppBarのユーティリティメソッド の setDisplayHomeAsUpEnabled()を呼び出してアップボタンを有効にする。
通常、子Activityの作成時に、onCreate()でToolbarを設定して、アップボタンを設定する。
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.ChildActivity);
Toolbar childToolbar = (Toolbar) findViewById(R.id.ChildToolbar);
setSupportActionBar(ChildToolbar);
ActionBar actionbar = getSupportActionBar();
actionbar.setDisplayHomeAsUpEnabled(true);
}
setDisplayHomeAsUpEnabled(true) を使えば onOptionItemSelected()でキャッチしなくても親Activityに移動できる。
Fragment利用
流れ
MainActivity.onCreate() -> activity_main.xml/<fragment> -> Fragment_Toolbar.onCreateView -> fragment_toolbar.xml
<application
...
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // <- レイアウト(activity_main.xml)を呼ぶ
}
}
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fragmentArea"
class="(packegeName).Fragment_Toolbar" // <- Fragment_Toolbar.classを呼ぶ
/>
public class Fragment_Toolbar extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
AppCompatActivity activity = (AppCompatActivity) getActivity();
View view = inflater.inflate(R.layout.fragment_toolbar,container.false);// <- レイアウト(fragment_toolbar)を呼びだしてインフレート!
Toolbar toolbar = view.findViewById(R.id.toolbar);
activity.setSupportActionBar(toolbar); // <- Toolbarをセット
setHasOptionsMenu(true); // menuを使えるようにする
return view;
}
// ToolbarにMenuを搭載する
@Override
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater){
super.onCreateOptionsMenu(menu,inflater);
inflater.inflate(R.menu.overflow_menu01,menu); // res/menu/overflow_menu01.xmlをToolbarにインフレート!
}
// Menu選択の分岐処理
@Override
public boolean onOptionsItemSelected(MenuItem item){
retun super.onOptionsItemSelected(item)
switch(item.getItemId()){
case R.id.menu01:
return true;
case R.id.menu02:
return true;
default
return super.onOptionsItemSelected(item);
}
}
}
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#aaa"
android:id="@+id/toolbar"
/>
style.xmlでToolbarのタイトル表示、タイトルの色設定
//res/value/style.xml
<resources>
// …
<style name = "Toolbar" >
<item name = "android:textColorPrimary">#fff</item>
<item name = "title>@string/app_name</item>
</style>
</resourced>
res/menu/overflow_menu01.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:title="MENU01"
android:id="@+id/menu01"
app:showAsAction="never"
/>
<item
android:title="MENU02"
android:id="@+id/menu02"
app:showAsActoion="never"
/>
</menu>
Fragmentで遷移した後に戻るボタンで戻るときには、
transaction.replace(R.id.fragmentArea,fragment);
transaction.addToBackStack(null); // <- ここでバックスタックに入れて管理する
transaction.commit();
Toolbar Style
例)
<resources>
<!-- 以下のレイアウトは Manifest で設定 -->
<style name="NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimaryDark">#fd0</item>
<item name="title">@string/app_name</item>
<item name="android:navigationBarColor">#fd0</item>
<item name="android:textColorPrimary">#fff</item> <!-- タイトルの色 -->
<item name="android:textColorSecondary">#fff</item> <!-- optionMenu印の色 -->
<item name="android:textColor">#f70</item> <!-- popupメニューのテキスト色 -->
<item name="colorAccent">@color/colorAccent</item>
</style>
<!-- 以下のレイアウトは androidx.appcompat.widget.Toolbar タグで設定 -->
<style name ="Toolbar">
<item name="android:background">#f70</item>
</style>
</resources>