LoginSignup
1
1

More than 3 years have passed since last update.

51歳から(現52)のプログラミング 備忘 Android Toolbar (アプリBar)

Last updated at Posted at 2020-02-12

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を作成して配置する。

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属性の値。

Activity.java
@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で親子関係を指定する例。

manifest.java
<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を設定して、アップボタンを設定する。

MainActivity.java
@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

AndroidManifest.xml
<application
    ...
    android:theme="@style/Theme.AppCompat.Light.NoActionBar">
MainActivity.java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); // <- レイアウト(activity_main.xml)を呼ぶ
    }
}
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を呼ぶ
   />
Fragment_Toolbar.java
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);
      }
   }
}
fragment_toolbar.xml
<androidx.appcompat.widget.Toolbar
   android:layout_width="match_parent"
   android:layout_height="?attr/actionBarSize"
   android:background="#aaa"
   android:id="@+id/toolbar"
   />

style.xmlでToolbarのタイトル表示、タイトルの色設定

style.xml
//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

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

例)

res/style.xml
<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>

   

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1