android menu pop彈出框的修改方案
阿新 • • 發佈:2019-01-31
前段時間公司針對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!!