4.0以降のオーバーフローメニューをICSデバイス(2.3〜2.1)以前)で使用したい。ActionBarSherlockでHoloEverywhereを使用しています。
私は次の解決策を試しました:
ActionBarSherlock&HoloEverywhere-強制オーバーフロー?
ただし、absForceOverflow
が存在しないため、機能しません。最新バージョンか何かで削除されましたか? ABSライブラリプロジェクトとHEライブラリプロジェクトの両方のR
ファイルを確認しましたが、フィールドがありません。
私のアプリのテーマは@style/Holo.Theme.Sherlock.Light
に設定されています。これは、継承元でabsForceOverflow
パラメータセットをtrue
に追加しようとしたテーマです。
バージョン4.2.0を使用している場合、.ForceOverflow
テーマは実際には削除されています。
ソース:バージョン4.2.0変更ログ
変更ログの抜粋:
Add SearchView widget for standard search interaction (API 8+ only)
Fix: ShareActionProvider in the split action bar no longer fills the entire screen.
Fix: ShareActionProvider now does file I/O on a background thread.
Fix: Automatically correct ColorDrawable not respecting bounds when used as a stacked background.
Fix: Ensure fragments collection is present before dispatching events.
Fix: XML-defined onClick searches the correct context for the declared method.
Fix: Ensure action mode start/finish callbacks are invoked on the activity for the native action bar.
Fix: Allow tab callbacks to have a fragment transaction instance for any FragmentActivity.
Fix: Ensure CollapsibleActionView callbacks are dispatched in both native and compatbility action bars.
Fix: Remove .ForceOverflow themes. These never should have been included.
オーバーフローを強制する必要がある場合は、以前のバージョンのABSをダウンロードする必要があります。ここでリリース履歴ごとのダウンロードのリストを取得できます: http://actionbarsherlock.com/download.html
現在、アプリに付随的な変更を加えたくないので、個人的にはまだABSバージョン4.1.0を使用しています。私はこれをtheme.xml
でも使用しています:
<style name="MyTheme" parent="@style/Theme.Sherlock.ForceOverflow">
<item name="Android:windowBackground">@color/background</item>
<item name="actionBarStyle">@style/Widget.Styled.ActionBar</item>
<item name="Android:actionBarStyle">@style/Widget.Styled.ActionBar</item>
</style>
<style name="MyTheme.ForceOverflow">
<item name="absForceOverflow">true</item>
</style>
そして、manifest.xml
でActivity
のテーマを適用している間、これを属性として使用します:"@style/Theme.SociallyYOU"
繰り返しますが、絶対にオーバーフローを強制する必要がある場合は、ここにある別の質問でCommonsWareの同じ考えを読むこともできます: https://stackoverflow.com/a/12872537/450534 。
注:つまり、トレードオフが重要でない場合は常に最新バージョンを使用することをお勧めします。オーバーフローメニューを強制する方法を投稿することで、古いバージョンを使用することを提案したり、推奨したりすることはありません。それは単に可能性を知らせているだけです。
ActionbarSherlock 4.2以降、オーバーフローメニューの可視性を管理する機能が失われました。それを機能させるには、2つのアプローチを組み合わせる必要があります。
Android 3.x(honeycomb)以上のメニューを強制的に表示するには、 this hack + add check Android version :
public static final int DEVICE_VERSION = Build.VERSION.SDK_INT;
public static final int DEVICE_HONEYCOMB = Build.VERSION_CODES.HONEYCOMB;
if (DEVICE_VERSION >= DEVICE_HONEYCOMB)
// Code from answer above
ハニカム前のデバイスのメニューを開きます。
ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.Java
、メソッドreserveOverflow
に移動しますオリジナルを次のものに置き換えます。
public static boolean reserveOverflow(Context context){return true; }
これにより、メニューが強制的に表示されます...
しかし、メニューボタンをクリックすると、メニューポップアップが表示されません。これを達成するには、これをオーバーライドする必要があります アクティビティ クラス:
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (DEVICE_VERSION < DEVICE_HONEYCOMB) {
if (event.getAction() == KeyEvent.ACTION_UP &&
keyCode == KeyEvent.KEYCODE_MENU) {
openOptionsMenu();
return true;
}
}
return super.onKeyUp(keyCode, event);
}
このアクションの後、すべてのAndroidバージョンで完全に機能するオーバーフローアクションバーメニューが表示されます。
Siddharth Leleが指摘している のように、実際のアクションバーと同じように動作するために、最後のABSバージョンで削除されました。したがって、一見、このメニューの表示をあきらめることが最良のオプションです。
ただし、一部のデバイスでは画面に表示され、他のデバイスでは表示されないオーバーフローメニューは、私の意見ではAndroidのアクションバーの大きな設計上の欠陥です。理由は次のとおりです。
ハードウェアメニューキーを備えたデバイスでは、メニューはアクションバーに表示されません。最近のデバイスでは、HWボタンの数を最小限に抑える傾向があります。これは、ユーザーフレンドリと見なされているためです(iPhoneにはボタンだけがないため、このデザインをコピーしているためです)。他のメーカーはメニューボタンを備えていますが、それを押さない限り非表示になっています(はい、ライトが不要になると点灯します。賢明なデザインではありませんが、すべてのボタンをオフにすると、電話はより不自然に見えます)。
これの意味をよりよく理解するために、例を見てみましょう:User A
には、メニューキー付きのデバイスがあります。彼はお気に入りのメールクライアントを使用しています。メールアカウントを設定するためのオプションは、通常のオプション(ヘルプ、バージョン情報など)とともにオーバーフローメニューに配置されます。彼は2つ目のアカウントを追加したいと思っていますが、このメニューにアクセスする方法についての手がかりがありません。彼が何をすべきかを理解するのに役立つ情報は画面にありません。したがって、ユーザーA
は、このメールクライアントも使用している友人B
に尋ねます。ユーザーB
は最新のNexusN + 1 Googlephoneを持っており、デバイスにHWメニューキーがないため、アクションバーにオーバーフローアイコンを表示できます。彼は、このメニューを開いて2番目のアカウントを追加する方法をA
に示しています。ユーザーA
は、同じアプリバージョンを使用しているため、完全に混乱しています。イライラしたA
は、電話が古すぎるために問題があると思うかもしれません。 B
も混乱しています。
この時点で、A
とB
の両方がスマートフォンの使い方を理解できない愚か者だと思っているかもしれません。しかし、デスクトップアプリとは異なり、スマートフォンユーザーの大多数は、デバイスの基本を知らないだけです。彼らの以前の電話は、単純なファームウェアを備えたキーパッドデバイスであった可能性があります。バッテリーが切れて交換のために店に行きましたが、在庫がありませんでした。彼らはインターネットで注文することもできたが、新しい電話を購入するよりも高額だった。それで、彼らはタッチスクリーン対応の電話を売られました。それが今日の電話のやり方だからです。今、彼らは本格的なOSを搭載した小さなコンピューターに直面する必要があります。さらに悪いことに、電話には「クイックスタートガイド」しか付属しておらず、完全なマニュアルを入手するには、インターネットからPDFをダウンロードする必要があります。何だと思う?彼らはしません。
モバイルアプリを開発している場合は、ユーザーがコンピューター、OS、または同様のアプリについて何も知らない可能性があると想定する必要があります。 GUIをデバイス間で同じようにして、人々がそれを使用する方法を学び、覚えられるようにする必要があります。アクションバーの設計者を責めないでください。A
やB
のようなユーザーがオプションメニューに移動する方法がわからない場合それはあなたのせいですそもそも。そのため、常に表示されるオプション画面にアクセスする手段を含める必要がありました。
戻るキーでも同様のことが起こります。一部のデバイスにはHWバックキーがある場合がありますが、新しいデバイスには通常ありません。しかし、アプリに戻ることができるときはいつでも、アクションバーにその矢印のようなボタンを常に表示しますよね?はい、一方のボタンが「ナビゲーションツリー」に戻り、もう一方のボタンが「過去にさかのぼる」ことはわかっていますが、これも設計上の欠陥です。平均的なユーザーにとっては、戻るだけです。画面にこのボタンがあり、ハードウェアボタンも使用できますが、これはオプションです。同じことがオーバーフローメニューでも行われているはずです。
したがって、(私のように)これが重要なボタンだと思っても、あきらめないでください。 通常のメインオプションメニューを提供し、それに適切なサブメニューを追加します。アクションボタンにして、説明的なアイコン、または次のようなテキストによる説明を割り当てます。 "メニュー"。オーバーフローメニューアイコンを模倣することもできます。次のいずれかのドローアブルを使用してください。
// For ActionBarSherlock
abs__ic_menu_moreoverflow_normal_holo_dark.png
abs__ic_menu_moreoverflow_normal_holo_light.png
// For ActionBar
ic_menu_moreoverflow_normal_holo_light.png
ic_menu_moreoverflow_normal_holo_dark.png
さらに、画像をプロジェクトのresフォルダーにコピーして貼り付けます。 ABSの将来のリリースまたはActionBarの次の実装にそれらが含まれるかどうかを知ることはできません。
Exterminator13の答えはある種のAndroidデバイス(私はかなり少ないと思います))では機能しないことがわかりましたが、できるだけ多くのデバイスに適合するために、ダイアログを使用して1つを使用しますAndroid:showAsAction = "always"をオーバーフローメニューボタンとして持つメニューです。結局のところ、アクションバーシャーロックのオーバーフローメニューの効果はそのソースによって実現されています。 、あなたも見ることができます 私のブログ 。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<item
Android:id="@+id/more"
Android:icon="@drawable/overflow"
Android:showAsAction="always"
/>
</menu>
private Dialog popupDialog;
private Boolean popupState=false;
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Android.R.id.home:
this.finish();
return true;
case R.id.more:
if (!popupState) {
showPop();
}else {
popupDialog.dismiss();
}
default:
return super.onOptionsItemSelected(item);
}
}
private void showPop(){
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(ResID, null);
ListView listView = (ListView) view.findViewById(ResID);
listView.setAdapter(yourOwnAdapter);
popupDialog = new Dialog(WifiAuthWireActivity.this);
popupDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
popupDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
popupDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
popupDialog.setContentView(view);
// Calculate ActionBar height
TypedValue tv = new TypedValue();
ActionBar maActionBar=getSupportActionBar();
int actionBarHeight=maActionBar.getHeight();
if (getTheme().resolveAttribute(Android.R.attr.actionBarSize, tv, true))
{
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}
WindowManager.LayoutParams wmlp = popupDialog.getWindow().getAttributes();
wmlp.gravity = Gravity.TOP | Gravity.RIGHT;
wmlp.x+=12;
wmlp.y+=actionBarHeight;
popupDialog.getWindow().setAttributes(wmlp);
popupDialog.show();
}