1. 程式人生 > >android menu pop彈出框的修改方案

android menu pop彈出框的修改方案

大哭  前段時間公司針對menu pop有個需求,需要彈出的menu pop框效果與小米的保持一致,在實現onCreateOptionsMenu方法的介面,對於豎屏顯示,點選menu鍵,彈出的menu panel寬度與手機螢幕保持一致,高度為內容的高度;對於橫屏的顯示,點選menu鍵,彈出的menu panel高度與手機螢幕寬度保持一致,寬度為包裹內容大小。

對於這個需求,感覺瞬間頭大了有木有,找不到修改點有木有。

檢視點選menu的流程,從Activity——onCreateOptionsMenu方法進行檢視,到PhoneWindow的onKeyUpPanel方法(中間的流程太繁瑣,可以自己去看),在此方法中呼叫了openPanel方法,

openPanel的時候,使用WindowManger的layoutParames來進行介面的flag控制,原生的是:

WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                width, WRAP_CONTENT,
                st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG,
                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                st.decorView.mDefaultOpacity);
下面為針對橫豎屏切換的程式碼控制:
int[] tempSt = makePanelFeatureState(st);
int[] widthAndHeight = makeLandMenuWidth();
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                widthAndHeight[0], widthAndHeight[1],
                tempSt[0],tempSt[1], WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG,
                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                st.decorView.mDefaultOpacity);
if(st.hasPanelItems()){
      lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
      lp.dimAmount = 0.5f;
}
 private boolean isLandDisplay(){
        Context context = getContext();
        return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
}
private int[] makePanelFeatureState(PanelFeatureState st){
        int[] temp = new int[]{st.x,st.y};
        if(isLandDisplay()){
            DisplayMetrics dm = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(dm);
            int screenWidth = dm.widthPixels;
            int screenHeigh = dm.heightPixels;
            temp[0] = 0;
            temp[1] = screenHeigh;
        }
        return temp;
}
private int[] makeLandMenuWidth(){
        int[] temp = new int[]{MATCH_PARENT,WRAP_CONTENT};
        if(isLandDisplay()){
            temp[0] = WRAP_CONTENT;
            temp[1] = MATCH_PARENT;
        }
        return temp;
}
public void onConfigurationChanged(Configuration newConfig) {方法中新增closeAllPanels();(解決橫豎屏切換介面重繪問題)
此處修改了橫豎屏時menu panel的顯示位置和寬高,針對menu item數量大於0時的介面進行設定flag為暗屏效果。
修改玩此處,介面的位置和大小就確認了,現在我們去找到其佈局檔案,在frameworks/base/core/res/res/layout/expanded_menu_layout.xml下面找到其佈局檔案,看到原生定義為:
<com.android.internal.view.menu.ExpandedMenuView xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+android:id/expanded_menu" 
	android:layout_width="?android:attr/panelMenuListWidth"
	android:layout_height="wrap_content" />

修改為:
<com.android.internal.view.menu.ExpandedMenuView xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+android:id/expanded_menu" 
	android:layout_width="fill_parent"
	android:layout_height="fill_parent" />
佈局檔案修改ok後,整體的顯示就已經確認了,最後一步,更改menu pop的背景,因為針對holo和holo.Light的主題,其在themes.xml檔案裡面的定義都是

<item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</item>

從core/res/res/drawable-xhdpi中找到此檔案為黑色顯示,做一張白色的.9圖片,放到目錄下,蔣新新增的圖片檔名配置到themes.xml檔案的holo.Light主題的

panelFullBackground中,到此為止,大功告成,顯示效果正常,與小米3一樣,可以鬆口氣了。

修改過程中的程式碼呼叫,資源配置等等沒有詳述,大家可以根據修改流程自己分析哈

GO HOME!!