用PopupWindow實現自定義overflow


當Action Bar的Action放不下時,系統會將其收集在overflow中。

用hierarchyviewer查看系統自己生成的Overflow,發現它本身就是popupWindow。

所以我們也可以用popUpWindow來寫自己的overflow實現更多功能,做出像微信一樣的效果。

第一次寫,廢話有點多,還望多包涵。

效果(GIF演示在文章底部):

最右邊的Action(那個三點菜單)是自己添加的Action,使用了android開發包里的圖標ic_action_overflow.png,可到官網下載。

首先在Item中添加Action,為了演示,添加了一個Submenu

<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="com.example.popupwindowoverflow.MainActivity" >
<item
        android:id="@+id/action_new"
        android:orderInCategory="1"
        android:title="SubMenu"
        android:icon="@drawable/ic_action_new"
        app:showAsAction="always">
    <menu>
        <item android:id="@+id/submenu1" 
            android:title="Accept" 
            android:titleCondensed="Accept"
            android:icon="@drawable/ic_action_accept" />
         <item android:id="@+id/submenu2" 
            android:title="Cancel" 
            android:titleCondensed="Cancel"
            android:icon="@drawable/ic_action_cancel" />
         <item android:id="@+id/submenu3" 
            android:title="Unread" 
            android:titleCondensed="Unread"
            android:icon="@drawable/ic_action_unread" />
    </menu>
</item>
<item
        android:id="@+id/action_overflow"
        android:orderInCategory="2"
        android:title="PopupWindow"
        android:icon="@drawable/ic_action_overflow"
        app:showAsAction="always"/>

</menu>

 

監聽ID為action_overflow的Action,創建popupWindow彈出自己的overflow。

 1     public boolean onOptionsItemSelected(MenuItem item) {
 2         // Handle action bar item clicks here. The action bar will
 3         // automatically handle clicks on the Home/Up button, so long
 4         // as you specify a parent activity in AndroidManifest.xml.       
 5         int id = item.getItemId();
 6         switch (id) {
 7         case R.id.action_overflow:
 8             popUpMyOverflow();//彈出自定義overflow
 9             return true;
10         }
11         return super.onOptionsItemSelected(item);
12     }

 

 下面介紹popUpMyOverflow()方法,就是通過它彈出了我們的overflow,自定義overflow的布局文件就是R.layout.action_overflow_popwindow,這里就不貼出來啦。

 1     public void popUpMyOverflow() {
 2         /**
 3          * 定位PopupWindow,讓它恰好顯示在Action Bar的下方。 通過設置Gravity,確定PopupWindow的大致位置。
 4          * 首先獲得狀態欄的高度,再獲取Action bar的高度,這兩者相加設置y方向的offset樣PopupWindow就顯示在action
 5          * bar的下方了。 通過dp計算出px,就可以在不同密度屏幕統一X方向的offset.但是要注意不要讓背景陰影大於所設置的offset,
 6          * 否則陰影的寬度為offset.
 7          */
 8         // 獲取狀態欄高度
 9         Rect frame = new Rect();
10         getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
11 //        狀態欄高度:frame.top
12         int xOffset = frame.top+getActionBar().getHeight()-25;//減去陰影寬度,適配UI.
13         int yOffset = Dp2Px(this, 5f); //設置x方向offset為5dp
14         View parentView = getLayoutInflater().inflate(R.layout.activity_main,
15                 null);
16         View popView = getLayoutInflater().inflate(
17                 R.layout.action_overflow_popwindow, null);
18         PopupWindow popWind = new PopupWindow(popView,
19                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);//popView即popupWindow的布局,ture設置focusAble.
20         
21         //必須設置BackgroundDrawable后setOutsideTouchable(true)才會有效。這里在XML中定義背景,所以這里設置為null;
22         popWind.setBackgroundDrawable(new BitmapDrawable(getResources(),
23                 (Bitmap) null));
24         popWind.setOutsideTouchable(true); //點擊外部關閉。
25         popWind.setAnimationStyle(android.R.style.Animation_Dialog);    //設置一個動畫。
26         //設置Gravity,讓它顯示在右上角。
27         popWind.showAtLocation(parentView, Gravity.RIGHT | Gravity.TOP,
28                 yOffset, xOffset);
29     }

 

在android中,為了適配不同屏幕密度和尺寸,android用了Dp單位,但是在Java代碼中多是接受px單位的尺寸,所以這里要轉換一下。

Dp轉換Px的方法。

1     public int Dp2Px(Context context, float dp) {
2         final float scale = context.getResources().getDisplayMetrics().density;
3         return (int) (dp * scale + 0.5f);
4     }

 

好的,現在我們有了所有要顯示自定義Overflow的東西了!運行你的app吧。

最終效果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM