如何设置窗口圆角及边框


转载请注明出处:http://blog.csdn.net/guxiao1201/article/details/41803379

 

在文章开头依然先贴出核心代码

@Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        View view = getWindow().getDecorView();
        WindowManager.LayoutParams lp = (WindowManager.LayoutParams)view.getLayoutParams();
        lp.gravity = Gravity.CENTER;
        lp.width = (dm.widthPixels * 4) / 5;
        lp.height = (dm.widthPixels * 4) / 5;
        getWindowManager().updateViewLayout(view,lp);
        getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        view.setBackgroundResource(R.drawable.dialog_activity_bg);
    }

上两篇博客说到了为什么在onAttachedToWindow中修改窗口尺寸和Window与DecorView之间的关系,这篇博客梳理下圆角实现代码逻辑。

整理思路为:

  • 获取屏幕尺寸,然后根据需求计算窗口Activity的尺寸。这里默认手机为竖屏,设置Activity的高和宽都为屏幕宽度的4/5。
  • 获取PhoneWindow的变量DecorView,然后修改DecorView的LayoutParams来实现修改窗口尺寸。
  • 设置PhoneWindow的背景为透明。
  • 设置DecorView的背景为带边框的圆角。

第一步通过经常使用的DisplayMetrics来获取屏幕高宽。

第二步通过getWindow().getDecorView()获取窗体的DecorView,然后再获取LayoutParams,不过DecorView的LayoutParams为WindowManager.LayoutParams。注意!根据上篇博客onAttachedToWindow()在整个Activity生命周期的位置及使用的分析,一定要再onAttachedToWindow中获取WindowManager.LayoutParams,否则获取的是空。

第三步直接调用PhoneWindow的setBackgroundDrawable接口设置成透明即可。

第四步为DecorView设置背景,下面贴出边框圆角的xml

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <corners
        android:radius="10.0dip"/>
    <solid
        android:color="#e5e5e6"/>
    <stroke
        android:color="#464646"
        android:width="2px"/>
</shape>

 

在测试过程中,我发现了一个很有意思的现象,如果先调用PhoneWindow的setBackground再调用DecorView的setBackground能正常显示,效果如下图

如何设置窗口圆角及边框_第1张图片

但若两行代码换换位置则显示效果如下图

如何设置窗口圆角及边框_第2张图片

好吧,要弄清楚这个问题依然是老办法——看源码。

查看PhoneWindow的setBackgroundDrawable

@Override
    public final void setBackgroundDrawable(Drawable drawable) {
        if (drawable != mBackgroundDrawable || mBackgroundResource != 0) {
            mBackgroundResource = 0;
            mBackgroundDrawable = drawable;
            if (mDecor != null) {
                mDecor.setWindowBackground(drawable);
            }
        }
    }

原来调用PhoneWindow的setBackgroundDrawable方法会调用DecorView的setWindowBackground方法

public void setWindowBackground(Drawable drawable) {
            if (getBackground() != drawable) {
                setBackgroundDrawable(drawable);
                if (drawable != null) {
                    drawable.getPadding(mBackgroundPadding);
                } else {
                    mBackgroundPadding.setEmpty();
                }
                drawableChanged();
            }
        }


在这里,DecorView会判断如果新传进来的Drawable和已经设置的Drawable不同则会替换背景为新的Drawable,所以如果先为DecorView设置带边框的圆角背景再给PhoneWindow设置透明背景,那么DecorView也会被设置成透明背景,也就是我们上图看到的效果。



 

 

 

你可能感兴趣的:(window,DecorView)