簡體   English   中英

ActionBarSherlock中的強制溢出菜單

[英]Force overflow menu in ActionBarSherlock

我希望4.0+溢出菜單用於預ICS設備(2.3 - 2.1)。 我正在使用帶ActionBarSherlock的HoloEverywhere。

我嘗試了以下解決方案:

ActionBarSherlock&HoloEverywhere - 強制溢出?

但它不起作用,因為absForceOverflow不存在。 是在最新版本中刪除了什么? 我已經檢查了ABS和HE庫項目的R文件,並且該字段根本就不存在。

我的應用程序的主題設置為@style/Holo.Theme.Sherlock.Light ,這是我嘗試繼承的主題,並將absForceOverflow參數設置為true

從ActionbarSherlock 4.2開始,我們失去了管理溢出菜單可見性的能力。 要使其工作,您需要結合兩種方法:

  1. 要強制Android 3.x(蜂窩)和鞋面的菜單可見性,您需要使用 hack + add check Android版本:

     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 
  2. 預蜂窩設備的打開菜單:

    • 打開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版本中被移除,以便與實際的Action Bar相同。 因此,乍一看放棄顯示此菜單是最佳選擇。

但是,在我看來,在某些設備的屏幕上顯示溢出菜單而不顯示其他設備,這是Android操作欄中的一個重大設計缺陷。 原因如下:

在具有硬件菜單鍵的設備中,菜單不會顯示在操作欄中。 最近設備的趨勢是將硬件按鈕的數量減少到最小,因為它被認為更加用戶友好(並且因為iphone沒有按鈕,所以他們復制了這個設計)。 其他制造商確實包括菜單按鈕,但它是隱藏的,除非你按下它(是的,當你不再需要燈時,它會亮起。不是明智的設計,但是當所有的按鈕都關閉時,手機看起來更加iphonish)。

為了更好地理解這個含義,讓我們看一個例子: 用戶A有一個帶菜單鍵的設備。 他正在使用他最喜歡的郵件客戶端。 配置郵件帳戶的選項放在溢出菜單中,以及常用選項(幫助,關於等)。 他想添加第二個帳戶,但他不知道如何進入這個菜單。 屏幕上沒有任何信息可以幫助他意識到該怎么做。 所以用戶A問他的朋友B ,他也在使用這個郵件客戶端。 用戶B擁有最新的Nexus N + 1 Googlephone,並且他能夠在操作欄中查看溢出圖標,因為他的設備沒有使用硬件菜單鍵。 他顯示了A如何通過打開此菜單添加第二個帳戶。 用戶A現在完全感到困惑,因為他們使用相同的應用程序版本。 沮喪, A可能會認為問題在於他的手機太老了。 B也很困惑。

在這一點上,你可能會認為AB都是無法理解如何使用智能手機的傻瓜。 但與桌面應用程序不同,絕大多數智能手機用戶不了解其設備的基礎知識。 他們以前的手機很可能是一個帶有簡單固件的鍵盤設備。 電池壞了,他們去了商店替換,但它缺貨了。 他們本可以在互聯網上訂購一台,但它比購買新手機更貴。 所以他們賣了一部支持觸摸屏的手機,因為這就是現在的手機。 現在,他們必須面對一台擁有完整操作系統的小型計算機。 更糟糕的是,手機只有一個“快速入門指南”,要獲得完整的手冊,他們必須從互聯網上下載pdf。 你猜怎么了? 他們不會。

如果您正在開發移動應用程序,您應該假設用戶可能不了解有關計算機,操作系統或類似應用程序的事情。 您應該使GUI在各種設備上看起來相似,以便人們可以學習並記住如何使用它。 不要責怪Action Bar設計師:如果像AB這樣的用戶不知道如何進入選項菜單, 那么首先就是你的錯 這就是為什么你應該包括一個始終可見的選項屏幕的方法。

后退鍵會發生類似的事情。 某些設備可能具有HW后備密鑰,較新的設備通常不具備。 但每當我們回到我們的應用程序時,我們總是在Action Bar中顯示箭頭狀按鈕,對吧? 是的,我知道一個按鈕在“導航樹”中導航,而另一個按鈕“回到過去”,但這也是另一個設計缺陷:對於普通用戶,后面只是回來了。 他在屏幕上有這個按鈕,他也可以使用HW,但這是可選的。 應該使用溢出菜單完成相同的操作。

所以如果你認為(像我一樣)這是一個重要的按鈕,不要放棄。 提供常規主選項菜單,並使用相關子菜單填充它。 將其設為操作按鈕並為其指定一個描述性圖標,甚至是“MENU”等文本描述。 您還可以模仿溢出菜單圖標,只需使用以下其中一個drawable:

    // 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

此外:將圖像復制粘貼到項目資源文件夾中。 您永遠不會知道ABS的未來版本或ActionBar的下一個實現是否會包含它們。

如果您使用的是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.xmlActivity應用主題時,我使用它作為屬性: "@style/Theme.SociallyYOU"

同樣,如果你必須絕對強制溢出,你可能還想在另一個問題中閱讀CommonsWare的想法: https//stackoverflow.com/a/12872537/450534

注意:話雖如此,如果權衡不重要,最好使用最新版本。 通過發布我強制溢出菜單的方式,我既不建議您使用舊版本,也不建議使用舊版本。 它只是告訴你可能性。

我發現Exterminator13的答案在某些Android設備上不起作用(我認為總數很小),但為了適應盡可能多的設備,我使用對話框並使用一個菜單與android:showAsAction =“always”作為溢出菜單按鈕。畢竟,actionbarsherlock的溢出菜單的效果是通過它的來源實現的,所以如果它不那么麻煩,為什么不實現我們自己的效果。 如果你懂中文,你也可以看我的博客

<?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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM