android 中毛玻璃效果(背景虚化)的实现

搜集很多关于背景虚化的帖子, @IcyFox 的见解 : 模糊实现方案探究

1. RenderScript

谈到高斯模糊,第一个想到的就是RenderScript。RenderScript是由Android3.0引入,用来在Android上编写高性能代码的一种语言(使用C99标准)。 引用官方文档的描述:

RenderScript runtime will parallelize work across all processors available on a device, such as multi-core CPUs, GPUs, or DSPs, allowing you to focus on expressing algorithms rather than scheduling work or load balancing.

为了在Android中使用RenderScript,我们需要(直接贴官方文档,比直译更通俗易懂):

  • High-performance compute kernels are written in a C99-derived language.
  • A Java API is used for managing the lifetime of RenderScript resources and controlling kernel execution.

学习文档:http://developer.android.com/guide/topics/renderscript/compute.html

上面两点总结成一句话为:我们需要一组compute kernels(.rs文件中编写),及一组用于控制renderScript相关的java api(.rs文件自动生成为java类)。 由于compute kernels的编写需要一定的学习成本,从JELLY_BEAN_MR1开始,Androied内置了一些compute kernels用于常用的操作,其中就包括了Gaussian blur

下面,通过实操来讲解一下RenderScript来实现高斯模糊,最终实现效果(讲文字背景进行模糊处理):

布局:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3. android:layout_width="match_parent"  
  4. android:layout_height="match_parent" >  
  5.   
  6.     <ImageView   
  7.         android:id="@+id/picture"   
  8.         android:layout_width="match_parent"   
  9.         android:layout_height="match_parent"   
  10.         android:src="@drawable/splash"   
  11.         android:scaleType="centerCrop" />  
  12.   
  13.     <TextView   
  14.         android:id="@+id/text"  
  15.         android:gravity="center_horizontal"   
  16.         android:layout_width="match_parent"  
  17.         android:layout_height="wrap_content"  
  18.         android:text="Gaussian Blur"  
  19.         android:textColor="@android:color/black"  
  20.         android:layout_gravity="center_vertical"  
  21.         android:textStyle="bold"  
  22.         android:textSize="48sp" />  
  23.   
  24.     <LinearLayout   
  25.         android:id="@+id/controls"   
  26.         android:layout_width="match_parent"   
  27.         android:layout_height="wrap_content"   
  28.         android:background="#7f000000"   
  29.         android:orientation="vertical"  
  30.         android:layout_gravity="bottom" />  
  31. </FrameLayout>  

核心代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void applyBlur() {  
  2.     image.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {  
  3.   
  4.         @Override  
  5.         public boolean onPreDraw() {  
  6.             image.getViewTreeObserver().removeOnPreDrawListener(this);  
  7.             image.buildDrawingCache();  
  8.             Bitmap bmp = image.getDrawingCache();  
  9.             blur(bmp, text, true);  
  10.             return true;  
  11.         }  
  12.     });  
  13. }  
  14.   
  15. @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)  
  16. private void blur(Bitmap bkg, View view) {  
  17.     long startMs = System.currentTimeMillis();  
  18.     float radius = 20;  
  19.   
  20.     Bitmap overlay = Bitmap.createBitmap((int)(view.getMeasuredWidth()), (int)(view.getMeasuredHeight()), Bitmap.Config.ARGB_8888);  
  21.     Canvas canvas = new Canvas(overlay);  
  22.     canvas.translate(-view.getLeft(), -view.getTop());  
  23.     canvas.drawBitmap(bkg, 00null);  
  24.   
  25.     RenderScript rs = RenderScript.create(SecondActivity.this);  
  26.   
  27.     Allocation overlayAlloc = Allocation.createFromBitmap(rs, overlay);  
  28.     ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, overlayAlloc.getElement());  
  29.     blur.setInput(overlayAlloc);  
  30.     blur.setRadius(radius);  
  31.     blur.forEach(overlayAlloc);  
  32.     overlayAlloc.copyTo(overlay);  
  33.     view.setBackground(new BitmapDrawable(getResources(), overlay));  
  34.     rs.destroy();  
  35.   
  36.     statusText.setText("cost " + (System.currentTimeMillis() - startMs) + "ms");  
  37. }  

当ImageView开始加载背景图时,取出它的drawableCache,进行blur处理,Gaussian blur的主要逻辑在blur函数中。对于在Java中使用RenderScript,文档中也有详细描述,对应到我们的代码,步骤为:

  • 初始化一个RenderScript Context.
  • 至少创建一个Allocation对象用于存储需要处理的数据.
  • 创建compute kernel的实例,本例中是内置的ScriptIntrinsicBlur对象.
  • 设置ScriptIntrinsicBlur实例的相关属性,包括Allocation, radius等.
  • 开始blur操作,对应(forEach).
  • 将blur后的结果拷贝回bitmap中。

此时,我们便得到了一个经过高斯模糊的bitmap。 

从上图可以看到,模糊处理花费了38ms(测试机为小米2s),由于Android假设每一帧的处理时间不能超过16ms(屏幕刷新频率60fps),因此,若在主线程里执行RenderScript操作,可能会造成卡顿现象。最好的方式是将其放入AsyncTask中执行。

此外,RenderScript在3.0引入,而一些内置的compute kernelJELLY_BEAN_MR1中引入,为了在低版本手机中使用这些特性,我们不得不引入renderscript_v8兼容包,对于手Q安装包增量的硬性指标,貌似只能放弃JELLY_BEAN_MR1以下的用户?

有点不甘心,想想别的解决方案吧。

2. FastBlur

由于高斯模糊归根结底是像素点的操作,也许在java层可以直接操作像素点来进行模糊化处理。google一下,果不其然,一个名为stackblur的开源项目提供了名为fastBlur的方法在java层直接进行高斯模糊处理。

项目地址请猛戳: stackblur

ok,现在来改造我们的程序.

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void blur(Bitmap bkg, View view) {  
  2.     long startMs = System.currentTimeMillis();  
  3.     float radius = 20;  
  4.   
  5.     Bitmap overlay = Bitmap.createBitmap((int)(view.getMeasuredWidth()), (int)(view.getMeasuredHeight()), Bitmap.Config.ARGB_8888);  
  6.     Canvas canvas = new Canvas(overlay);  
  7.     canvas.translate(-view.getLeft(), -view.getTop());  
  8.     canvas.drawBitmap(bkg, 00null);  
  9.     overlay = FastBlur.doBlur(overlay, (int)radius, true);  
  10.     view.setBackground(new BitmapDrawable(getResources(), overlay));  
  11.     statusText.setText("cost " + (System.currentTimeMillis() - startMs) + "ms");  
  12. }    

这里,仅仅是把RenderScript相关的操作换成了FastBlur提供的api。效果图如下: 

效果还不错,与RenderScript的实现差不多,但花费的时间却整整多了2倍多,这完全是无法接受的。好吧,只能继续探究。

3. AdvancedFastBlur

stackOverflow对于程序员来说永远是最大的宝藏。http://stackoverflow.com/questions/2067955/fast-bitmap-blur-for-android-sdk这篇提问帖终于提供了新的解决思路:

This is a shot in the dark, but you might try shrinking the image and then enlarging it again. This can be done with Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter). Make sure and set the filter parameter to true. It'll run in native code so it might be faster.

它所表述的原理为先通过缩小图片,使其丢失一些像素点,接着进行模糊化处理,然后再放大到原来尺寸。由于图片缩小后再进行模糊处理,需要处理的像素点和半径都变小,从而使得模糊处理速度加快。 了解原理,继续改善:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void blur(Bitmap bkg, View view) {  
  2.     long startMs = System.currentTimeMillis();  
  3.     float radius = 2;  
  4.     float scaleFactor = 8;  
  5.   
  6.     Bitmap overlay = Bitmap.createBitmap((int)(view.getMeasuredWidth()/scaleFactor), (int)(view.getMeasuredHeight()/scaleFactor), Bitmap.Config.ARGB_8888);  
  7.     Canvas canvas = new Canvas(overlay);  
  8.     canvas.translate(-view.getLeft()/scaleFactor, -view.getTop()/scaleFactor);  
  9.     canvas.scale(1 / scaleFactor, 1 / scaleFactor);  
  10.     Paint paint = new Paint();  
  11.     paint.setFlags(Paint.FILTER_BITMAP_FLAG);  
  12.     canvas.drawBitmap(bkg, 00, paint);  
  13.     overlay = FastBlur.doBlur(overlay, (int)radius, true);  
  14.     view.setBackground(new BitmapDrawable(getResources(), overlay));  
  15.     statusText.setText("cost " + (System.currentTimeMillis() - startMs) + "ms");  
  16. }   

最新的代码所创建的bitmap为原图的1/8大小,接着,同样使用fastBlur来进行模糊化处理,最后再为textview设置背景,此时,背景图会自动放大到初始大小。注意,由于这里进行了缩放,radius的取值也要比之前小得多(这里将原始取值除以8得到近似值2)。下面是效果图:

惊呆了有木有!!效果一样,处理速度却快得惊人。它相对于renderScript方案来说,节省了拷贝bitmap到Allocation中,处理完后再拷贝回来的时间开销。

4. Warning

由于FastBlur是将整个bitmap拷贝到一个临时的buffer中进行像素点操作,因此,它不适合处理一些过大的背景图(很容导致OOM有木有~)。对于开发者来说,RenderScript方案和FastBlur方案的选择,需要你根据具体业务来衡量!










1、如果系统的api在16以上,可以使用系统提供的方法直接处理图片

if (VERSION.SDK_INT > 16) {
            Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);


            final RenderScript rs = RenderScript.create(context);
            final Allocation input = Allocation.createFromBitmap(rs, sentBitmap, Allocation.MipmapControl.MIPMAP_NONE,
                    Allocation.USAGE_SCRIPT);
            final Allocation output = Allocation.createTyped(rs, input.getType());
            final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
            script.setRadius(radius /* e.g. 3.f */);
            script.setInput(input);
            script.forEach(output);
            output.copyTo(bitmap);
            return bitmap;
        }


2、 如果Api条件不满足,可以使用如下方法

@SuppressLint("NewApi")
    public static Bitmap fastblur(Context context, Bitmap sentBitmap, int radius) {


        
        Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);


        if (radius < 1) {
            return (null);
        }


        int w = bitmap.getWidth();
        int h = bitmap.getHeight();


        int[] pix = new int[w * h];
//        Log.e("pix", w + " " + h + " " + pix.length);
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);


        int wm = w - 1;
        int hm = h - 1;
        int wh = w * h;
        int div = radius + radius + 1;


        int r[] = new int[wh];
        int g[] = new int[wh];
        int b[] = new int[wh];
        int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
        int vmin[] = new int[Math.max(w, h)];


        int divsum = (div + 1) >> 1;
        divsum *= divsum;
        int temp = 256 * divsum;
        int dv[] = new int[temp];
        for (i = 0; i < temp; i++) {
            dv[i] = (i / divsum);
        }


        yw = yi = 0;


        int[][] stack = new int[div][3];
        int stackpointer;
        int stackstart;
        int[] sir;
        int rbs;
        int r1 = radius + 1;
        int routsum, goutsum, boutsum;
        int rinsum, ginsum, binsum;


        for (y = 0; y < h; y++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            for (i = -radius; i <= radius; i++) {
                p = pix[yi + Math.min(wm, Math.max(i, 0))];
                sir = stack[i + radius];
                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);
                rbs = r1 - Math.abs(i);
                rsum += sir[0] * rbs;
                gsum += sir[1] * rbs;
                bsum += sir[2] * rbs;
                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }
            }
            stackpointer = radius;


            for (x = 0; x < w; x++) {


                r[yi] = dv[rsum];
                g[yi] = dv[gsum];
                b[yi] = dv[bsum];


                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;


                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];


                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];


                if (y == 0) {
                    vmin[x] = Math.min(x + radius + 1, wm);
                }
                p = pix[yw + vmin[x]];


                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);


                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];


                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;


                stackpointer = (stackpointer + 1) % div;
                sir = stack[(stackpointer) % div];


                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];


                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];


                yi++;
            }
            yw += w;
        }
        for (x = 0; x < w; x++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            yp = -radius * w;
            for (i = -radius; i <= radius; i++) {
                yi = Math.max(0, yp) + x;


                sir = stack[i + radius];


                sir[0] = r[yi];
                sir[1] = g[yi];
                sir[2] = b[yi];


                rbs = r1 - Math.abs(i);


                rsum += r[yi] * rbs;
                gsum += g[yi] * rbs;
                bsum += b[yi] * rbs;


                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }


                if (i < hm) {
                    yp += w;
                }
            }
            yi = x;
            stackpointer = radius;
            for (y = 0; y < h; y++) {
                // Preserve alpha channel: ( 0xff000000 & pix[yi] )
                pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];


                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;


                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];


                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];


                if (x == 0) {
                    vmin[y] = Math.min(y + r1, hm) * w;
                }
                p = x + vmin[y];


                sir[0] = r[p];
                sir[1] = g[p];
                sir[2] = b[p];


                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];


                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;


                stackpointer = (stackpointer + 1) % div;
                sir = stack[stackpointer];


                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];


                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];


                yi += w;
            }
        }


//        Log.e("pix", w + " " + h + " " + pix.length);
        bitmap.setPixels(pix, 0, w, 0, 0, w, h);
        return (bitmap);
    }

3、以上方法都存在一个问题,性能较低,下面提供一个C实现

static int* StackBlur(int* pix, int w, int h, int radius) {
    int wm = w - 1;
    int hm = h - 1;
    int wh = w * h;
    int div = radius + radius + 1;


    int *r = (int *)malloc(wh * sizeof(int));
    int *g = (int *)malloc(wh * sizeof(int));
    int *b = (int *)malloc(wh * sizeof(int));
    int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;


    int *vmin = (int *)malloc(MAX(w,h) * sizeof(int));


    int divsum = (div + 1) >> 1;
    divsum *= divsum;
    int *dv = (int *)malloc(256 * divsum * sizeof(int));
    for (i = 0; i < 256 * divsum; i++) {
        dv[i] = (i / divsum);
    }


    yw = yi = 0;


    int(*stack)[3] = (int(*)[3])malloc(div * 3 * sizeof(int));
    int stackpointer;
    int stackstart;
    int *sir;
    int rbs;
    int r1 = radius + 1;
    int routsum, goutsum, boutsum;
    int rinsum, ginsum, binsum;


    for (y = 0; y < h; y++) {
        rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
        for (i = -radius; i <= radius; i++) {
            p = pix[yi + (MIN(wm, MAX(i, 0)))];
            sir = stack[i + radius];
            sir[0] = (p & 0xff0000) >> 16;
            sir[1] = (p & 0x00ff00) >> 8;
            sir[2] = (p & 0x0000ff);


            rbs = r1 - ABS(i);
            rsum += sir[0] * rbs;
            gsum += sir[1] * rbs;
            bsum += sir[2] * rbs;
            if (i > 0) {
                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];
            }
            else {
                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];
            }
        }
        stackpointer = radius;


        for (x = 0; x < w; x++) {


            r[yi] = dv[rsum];
            g[yi] = dv[gsum];
            b[yi] = dv[bsum];


            rsum -= routsum;
            gsum -= goutsum;
            bsum -= boutsum;


            stackstart = stackpointer - radius + div;
            sir = stack[stackstart % div];


            routsum -= sir[0];
            goutsum -= sir[1];
            boutsum -= sir[2];


            if (y == 0) {
                vmin[x] = MIN(x + radius + 1, wm);
            }
            p = pix[yw + vmin[x]];


            sir[0] = (p & 0xff0000) >> 16;
            sir[1] = (p & 0x00ff00) >> 8;
            sir[2] = (p & 0x0000ff);


            rinsum += sir[0];
            ginsum += sir[1];
            binsum += sir[2];


            rsum += rinsum;
            gsum += ginsum;
            bsum += binsum;


            stackpointer = (stackpointer + 1) % div;
            sir = stack[(stackpointer) % div];


            routsum += sir[0];
            goutsum += sir[1];
            boutsum += sir[2];


            rinsum -= sir[0];
            ginsum -= sir[1];
            binsum -= sir[2];


            yi++;
        }
        yw += w;
    }
    for (x = 0; x < w; x++) {
        rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
        yp = -radius * w;
        for (i = -radius; i <= radius; i++) {
            yi = MAX(0, yp) + x;


            sir = stack[i + radius];


            sir[0] = r[yi];
            sir[1] = g[yi];
            sir[2] = b[yi];


            rbs = r1 - ABS(i);


            rsum += r[yi] * rbs;
            gsum += g[yi] * rbs;
            bsum += b[yi] * rbs;


            if (i > 0) {
                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];
            }
            else {
                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];
            }


            if (i < hm) {
                yp += w;
            }
        }
        yi = x;
        stackpointer = radius;
        for (y = 0; y < h; y++) {
            // Preserve alpha channel: ( 0xff000000 & pix[yi] )
            pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];


            rsum -= routsum;
            gsum -= goutsum;
            bsum -= boutsum;


            stackstart = stackpointer - radius + div;
            sir = stack[stackstart % div];


            routsum -= sir[0];
            goutsum -= sir[1];
            boutsum -= sir[2];


            if (x == 0) {
                vmin[y] = MIN(y + r1, hm) * w;
            }
            p = x + vmin[y];


            sir[0] = r[p];
            sir[1] = g[p];
            sir[2] = b[p];


            rinsum += sir[0];
            ginsum += sir[1];
            binsum += sir[2];


            rsum += rinsum;
            gsum += ginsum;
            bsum += binsum;


            stackpointer = (stackpointer + 1) % div;
            sir = stack[stackpointer];


            routsum += sir[0];
            goutsum += sir[1];
            boutsum += sir[2];


            rinsum -= sir[0];
            ginsum -= sir[1];
            binsum -= sir[2];


            yi += w;
        }
    }


    free(r);
    free(g);
    free(b);
    free(vmin);
    free(dv);
    free(stack);
    return(pix);
}


推荐使用  方式二。 stackblur 在 github上面的 下载地址 :https://github.com/kikoso/android-stackblur


下面是设置透明效果 大概有三种

1、用android系统的透明效果
Java代码 
android:background="@android:color/transparent" 

例如 设置按钮
Java代码 
<Button android:background="@android:color/transparent"  
 
  android:text="@+id/Button01"  
 
  android:id="@+id/Button01"  
 
  android:layout_width="wrap_content"  
 
  android:layout_height="wrap_content"  
 
  android:textColor="#ffffff" />  

2、用ARGB来控制
Java代码 
半透明<Button android:background="#e0000000" /> 
透明<Button android:background="#00000000" /> 
 
3、设置alpha
Java代码 
View v = findViewById(R.id.content);//找到你要设透明背景的layout 的id 
v.getBackground().setAlpha(100);//0~255透明度值 
 
 
 
 
 
 

android 窗体透明的,黑暗度等的设置技巧
设置透明度(这是窗体本身的透明度,非背景)
lp.alpha=
1
.5f;
31
<code bitstream="" vera="" sans="" mono',="" 'courier="" new',="" courier,="" monospace="" !important;="" float:="" none="" border-top-width:="" 0px="" border-bottom-width:="" height:="" auto="" color:="" rgb(0,0,0)="" font-size:="" 10pt="" vertical-align:="" baseline="" border-left-width:="" top:="" right:="" font-weight:="" normal="" padding-top:="" left:="" background-origin:="" initial;="" background-clip:="" initial"="" class="plain" style="margin: 0px; padding: 0px !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; left: auto !important; line-height: 1.1em !important; outline: 0px !important; overflow: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 1em !important; min-height: inherit !important; background: none !important;">WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
以上设置对dialog对话框同样有效
 
 
 
Activity的透明、半透明效果的设置transparent
res/values/styles.xml
1
2
3
4
5
6
7
8
9
10
11
12
<resources>  
   <style name="Transparent">  
     <item name="android:windowBackground">
       @color/transparent_background
     </item>  
     <item name="android:windowNoTitle">true </item>  
     <item name="android:windowIsTranslucent">true </item>    
     <item name="android:windowAnimationStyle">
         @+android:style/Animation.Translucent
    </item>  
   </style>  
</resources>
res/values/color.xml
1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>  
<resources>  
   <color name="transparent_background">#50000000 </color>  
</resources>  
//注意:
//color.xml的#5000000前两位是透明的效果参数从00--99(透明--不怎么透明),
//后6位是颜色的设置
manifest.xml
1
2
3
4
<activity 
android:name=".TransparentActivity" 
android:theme="@style/Transparent">  
</activity>
java代码

1
2
3
4
5
public  void onCreate (Bundle savedInstanceState )  {  
         super. onCreate (savedInstanceState ) ;  
        setTheme (R. style. Transparent ) ;   
        setContentView (R. layout. transparent ) ;  
}
http://blog.csdn.net/xfcy_hades/article/details/43952381

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值