この記事では、ユーザーが1つのアクティビティ内で4つの異なる方法でコンテンツを操作できる動的なツールバーの作成についてお話します。 xmlスタイルファイルで始まり、アイコンアニメーションで終わるツールバー開発のプロセス全体を見ていきます。記事の最後に、完全に機能するアプリケーションの例を含むGitHubリポジトリへのリンクを残します。
問題のステートメントから始めましょう
ユーザーが株価の変化を監視できるアプリケーション用のツールバーを開発します。 ユーザーがフォローしているすべての共有のリストがメイン画面に表示されます。共有の削除、検索、並べ替えなどの基本機能も実装する必要があります。 これは、動的ツールバーを使用してこの機能を実装する方法です。
標準モード | 検索モード | 削除モード | ソートモード |
---|---|---|---|
XML構成ファイルを作成する
そのため、まず、ツールバー自体のxmlファイルを作成する必要があります。 これは別のファイルで行うことをお勧めします。将来的には、アプリケーションのすべてのアクティビティで同じ(または類似の)ツールバーを使用する可能性が高くなるためです。
res / layout / toolbar.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/toolbar_actionbar" android:layout_width="match_parent" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:layout_height="?android:actionBarSize" android:background="@color/toolbar_orange"/>
次のように、xmlアクティビティにtoolbar.xmlを追加できます。
res / layout / activity_main.xml
<include layout="@layout/toolbar" />
検索ウィジェットはツールバーにあるため、アプリケーションのstyles.xmlファイルでその外観を構成できます。 21バージョンのAndroid SDKには、検索ウィジェット(SearchViewウィジェット)をカスタマイズするためのより多くのオプションがあります。属性の完全なリストは、このリンクで見ることができます: AppCompat v21-Pre-Lollipopデバイスのマテリアルデザイン! 同じファイルで、ツールバーの色を設定します。
res / values / styles.xml
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="colorPrimaryDark">@color/status_bar_orange</item> <item name="searchViewStyle">@style/AppSearchViewStyle</item> </style> <style name="AppSearchViewStyle" parent="Widget.AppCompat.SearchView"> <item name="android:textCursorDrawable">@drawable/white_cursor</item> <item name="queryBackground">@android:color/transparent</item> <item name="searchIcon">@drawable/icon_toolbar_search</item> <item name="closeIcon">@drawable/icon_toolbar_clear</item> <item name="queryHint">@string/search_hint</item> <item name="android:imeActionId">6</item> </style> </resources>
最後に、ツールバーのすべての要素のリストを含むファイルを作成します。 ここにはいくつかのオプションがあります:
- 最初に、標準モードで表示される要素のみを作成し、モードを切り替えるときにコード内の要素を追加または削除します。
- xmlファイルにすべての既存の要素をすぐに作成し、コード内でそれらの可視性を制御するだけです。
2番目のオプションを選択したのは、ツールバー内に多くの要素がなく、そこに表示される要素のみを保存してメモリを節約する意味がないからです。
ツールバー要素を作成する方法も2つあります。
- クラスMenuItemのインスタンスとして、メニュー(Menu)内にアイテムを作成します。 このメソッドは、ツールバーがまだなかった以前のバージョンのAnrdroid(APIレベル<21)で使用されていました。
- toolbar.xmlファイル内に通常のビューとしてすべての要素を作成します。
メニューメソッドを使用することにしました。まず、ツールバーの独自のレイアウトを作成する必要がないためです。 第二に、下位互換性に問題はありません。第三に、ツールバーとナビゲーションドロワー(アプリケーションに存在し、MenuItemで動作するActionBarDrawerToggleによって制御されるサイドメニュー)の競合を回避します。
res / menu / menu_activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:yourapp="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_search" android:title="@android:string/search_go" android:icon="@drawable/icon_toolbar_search" yourapp:showAsAction="always|collapseActionView" yourapp:actionViewClass="android.support.v7.widget.SearchView" /> <item android:id="@+id/action_edit" android:title="@string/edit" android:icon="@drawable/icon_toolbar_edit" yourapp:showAsAction="ifRoom" /> <item android:id="@+id/action_micro" android:title="@string/microphone" android:icon="@drawable/icon_toolbar_micro" yourapp:showAsAction="always" /> <item android:id="@+id/action_remove" android:title="@string/remove" android:icon="@drawable/icon_toolbar_remove" yourapp:showAsAction="always" /> <item android:id="@+id/action_sort" android:title="@string/sort_ab" android:icon="@drawable/icon_toolbal_sort" yourapp:showAsAction="always" /> </menu>
アクティビティにツールバーを追加
すべてのxmlファイルが作成され、ツールバーをアクティビティに追加できるようになりました。 最初に 、メニューの初期化を担当するonCreateOptionsMenuメソッドを書き直しましょう 。
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_activity_main, menu); return true; }
次に、ツールバーをActioanBarとして設定します。これにより、以前のバージョンのAndroid(APIレベル<21)との後方互換性が提供されます。
@Override protected void onCreate(Bundle savedInstanceState) { Toolbar mActionBarToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar); setSupportActionBar(mActionBarToolbar); }
ツールバー要素の管理
githubのサンプルリポジトリの要素を管理する完全なコードを見ることができ、記事では主な方法に焦点を当てます。
- OnOptionsItemSelected(MenuItem item)メソッド-ツールバー内の項目をクリックすると呼び出されます
- メソッドonMenuItemActionExpand(MenuItemアイテム) -検索ウィジェットがアクティブ状態になると呼び出されます。 このメソッドを呼び出すには、MenuItemCompat.OnActionExpandListenerインターフェイスを実装し、MenuItem検索用に設定する必要があります。
MenuItemCompat.setOnActionExpandListener(searchMenuItem, this); //this - MenuItemCompat.OnActionExpandListener
- OnMenuItemActionCollapseメソッド-検索ウィジェットが閉じられたときに呼び出されます; OnActionExpandListenerインターフェイスも実装する必要があります。 たとえば、ユーザーが[戻る]ボタンをクリックしたときに、人為的に呼び出すこともできます。 例:
@Override public void onBackPressed() { if (mode == Mode.SEARCH) searchMenuItem.collapseActionView(); }
ツールバー要素のアニメーション化
アニメーションを作成するために、 AndroidViewAnimationsライブラリーを使用しました 。 このライブラリは、ViewクラスオブジェクトまたはViewを継承するクラスオブジェクトをアニメーション化できます。 ツールバー要素のアニメーションを作成するときに発生する主な問題は、Viewクラスのオブジェクトがないことです。 アニメーション化するアイテムのMenuItemのみがあります。
たとえば、検索アイコンを使用して自分で作成したMenuItemを使用する場合、そのビューの取得は非常に簡単です。
MenuItem searchMenuItem = menu.findItem(R.id.action_search); View searchItemView = findViewById(searchMenuItem.getItemId());
ツールバーシステム要素のビュー、たとえば、検索モード(検索モードのスクリーンショットを参照)で表示される戻る矢印を取得する場合、事態は複雑になります。 この矢印のIDがわからないため、 Fieldを使用する必要があります。これにより、クラスの任意のメンバーに動的にアクセスできます。 この場合、戻る矢印はToolbarクラスのメンバーですが、開始する前にクラス内の矢印の名前を見つける必要があります。 Androidソースコードに移動し、 Toolbarクラスを開いて 、100行目の「mNavButtonView」という名前の矢印を見つけます。 ビュー矢印を取得してアニメーション化するサンプルコード:
// View ImageButton btnToolbarButton = null; try { Toolbar mActionBarToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar); Field fNavBtn = mActionBarToolbar.getClass().getDeclaredField("mNavButtonView"); fNavBtn.setAccessible(true); btnToolbarButton = (ImageButton) fNavBtn .get(mActionBarToolbar); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } // if(btnToolbarButton!=null) YoYo.with(Techniques.FlipInX).duration(850).playOn(btnToolbarButton);
おわりに
この記事では、動的なツールバーを作成するプロセスと、その要素を操作する方法を検討しました。 残念なことに、1つの記事のフレームワーク内では、すべてのニュアンスを完全に検討してすべてのコードを解析することは不可能です。