自定义overflow菜单的实现(PopupWindow)

Home / Android MrLee 2015-3-23 3744

当Action Bar的Action放不下时,系统会将其收集在overflow中。
用hierarchyviewer查看系统自己生成的Overflow,发现它本身就是popupWindow。
所以我们也可以用popUpWindow来写自己的overflow实现更多功能,做出像微信一样的效果。

171136449906187

最右边的Action(那个三点菜单)是自己添加的Action,使用了android开发包里的图标ic_action_overflow.png,可到官网下载。
首先在Item中添加Action,为了演示,添加了一个Submenu


    
        
         
         
    



监听ID为action_overflow的Action,创建popupWindow弹出自己的overflow。
public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.       
        int id = item.getItemId();
        switch (id) {
        case R.id.action_overflow:
            popUpMyOverflow();//弹出自定义overflow
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
下面介绍popUpMyOverflow()方法,就是通过它弹出了我们的overflow,自定义overflow的布局文件就是R.layout.action_overflow_popwindow,这里就不贴出来啦。
public void popUpMyOverflow() {
        /**
         * 定位PopupWindow,让它恰好显示在Action Bar的下方。 通过设置Gravity,确定PopupWindow的大致位置。
         * 首先获得状态栏的高度,再获取Action bar的高度,这两者相加设置y方向的offset样PopupWindow就显示在action
         * bar的下方了。 通过dp计算出px,就可以在不同密度屏幕统一X方向的offset.但是要注意不要让背景阴影大于所设置的offset,
         * 否则阴影的宽度为offset.
         */
        // 获取状态栏高度
        Rect frame = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
//        状态栏高度:frame.top
        int xOffset = frame.top+getActionBar().getHeight()-25;//减去阴影宽度,适配UI.
        int yOffset = Dp2Px(this, 5f); //设置x方向offset为5dp
        View parentView = getLayoutInflater().inflate(R.layout.activity_main,
                null);
        View popView = getLayoutInflater().inflate(
                R.layout.action_overflow_popwindow, null);
        PopupWindow popWind = new PopupWindow(popView,
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);//popView即popupWindow的布局,ture设置focusAble.
        
        //必须设置BackgroundDrawable后setOutsideTouchable(true)才会有效。这里在XML中定义背景,所以这里设置为null;
        popWind.setBackgroundDrawable(new BitmapDrawable(getResources(),
                (Bitmap) null));
        popWind.setOutsideTouchable(true); //点击外部关闭。
        popWind.setAnimationStyle(android.R.style.Animation_Dialog);    //设置一个动画。
        //设置Gravity,让它显示在右上角。
        popWind.showAtLocation(parentView, Gravity.RIGHT | Gravity.TOP,
                yOffset, xOffset);
    }
在android中,为了适配不同屏幕密度和尺寸,android用了Dp单位,但是在Java代码中多是接受px单位的尺寸,所以这里要转换一下。
Dp转换Px的方法。
public int Dp2Px(Context context, float dp) {
    final float scale = context.getResources().getDisplayMetrics().density;
    return (int) (dp * scale + 0.5f);
}
最终效果:

171210432875743

本文链接:https://www.it72.com/1522.htm

推荐阅读
最新回复 (0)
返回