ShareActionProvider
ICS以降、ActionBarに共有MenuItemを置く際、共有履歴を表示することができるようになった。
ShareActionProviderはその実装のための仕組みとして導入された。
実装
まず、menu定義に共有MenuItemを定義する。
このとき、android:actionProviderClass
属性にandroid.widget.ShareActionProvider
を定義する。
この属性を定義すると自動的に共有アイコンも設定される。
android:showAsAction
はnever
でも正常に動作するが、最新履歴の表示がなくなってしまうためifroom
かalways
が良いだろう。
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MyActivity">
<item
android:id="@+id/action_share_always"
android:actionProviderClass="android.widget.ShareActionProvider"
android:showAsAction="always"
android:title="@string/action_share" />
</menu>
次に、ソースコード側でMenuItemの設定を行う。
ShareActionProvider
を使用する場合、共有アクションで実行するIntent
もonCreateOptionsMenu
で指定できてしまうため、onOptionsItemSelected
での処理は特に必要なくなる。
また、下の例ではShareCompat.IntentBuilder
を利用しているが、普通にIntent
を生成してsetShareIntent
しても問題なく動く。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
// ShareActionProvider の設定
MenuItem actionItem = menu.findItem(R.id.action_share_always);
ShareActionProvider actionProvider = (ShareActionProvider) actionItem.getActionProvider();
// インテントの設定
Intent shareIntent = ShareCompat.IntentBuilder.from(this)
.setText("hogehoge")
.setType("text/plain")
.getIntent();
// ShareActionProviderにインテントの設定
actionProvider.setShareIntent(shareIntent);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// 何も書かなくてOK
return super.onOptionsItemSelected(item);
}
動作
はじめて共有アイコンをタップした場合、以下のようなポップアップが表示される。
すべてを表示→Twitterを選択し、Twitterから戻るとこのような画面になっている。
複数のアプリで共有を試すと左側の共有アイコンタップで表示されるポップアップも最新以前の履歴になっていることがわかる。
ShareCompat
ShareActionProvider
は便利だがICS以降でしか実装ができない。
ICS以前の端末に対応したアプリで同様の実装を行うためにはSupportLibrary
のShareCompat
を利用する。
ただし、ShareCompat
を使ってもICS以前の端末で履歴が表示されるわけではない。
この辺りはNotificationCompat
等と一緒だ。
実装
ShareCompat
で実装を行う場合、menu定義では特別な表記は必要ない。
ただし、デフォルトの共有アイコンが設定されないため、こちらは定義する必要がある。
<menu 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"
tools:context=".MyActivity">
<item
android:id="@+id/action_share_always"
android:icon="@android:drawable/ic_menu_share"
android:title="共有"
app:showAsAction="always" />
</menu>
ソースコード側の処理はShareActionProvider
を使用していた部分をShareCompat
で書きなおすような形になる。
ShareActionProvider
同様、onOptionsItemSelected
での処理は特に必要ない。
ただし、Intent
ではなくShareCompat.IntentBuilder
を渡すことになるため、若干の制限が生じる。
たとえば、ShareCompat.IntentBuilder
ではsetAction()
ができないため、ACTION_SEND
かACTION_SEND_MULTIPLE
以外のアクションが指定できないようだ(ちょっと自信がない…)。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my, menu);
// IntentBuilderの生成
ShareCompat.IntentBuilder builder = ShareCompat.IntentBuilder.from(this);
builder.setText("hogehoge")
.setType("text/plain");
// MenuItemにShareアクションの設定
ShareCompat.configureMenuItem(menu, R.id.action_share_always, builder);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
動作
ICS以降の端末での挙動はShareActionProvider
と変わらない。
それ以前の端末ではmenuのxmlで指定したアイコンのみが表示され、タップ時にはIntentBuilder
で生成したIntent
が発行される。
物理メニューボタンのある機種でも同様。
まとめ
ActionBarに共有ボタンを置くAndroidアプリは多い。
ShareActionProvider
、ShareCompat
を使うと(ICS以降だけだが)非常に少ない手間で共有ボタンをリッチにできるため、かなり便利だと思う。
個人的にも便利なので、アプリ作成者はどんどん実装してほしい。