Android滚动截屏,ScrollView截屏

在做分享功能的时候,需要截取全屏内容,一屏展示不完的内容,一般我们会用到 ListView 或 ScrollView


一: 普通截屏的实现

获取当前Window 的 DrawingCache 的方式,即decorView的DrawingCache

    /**
     * shot the current screen ,with the status but the status is trans *
     *
     * @param ctx current activity
     */
    public static Bitmap shotScreen(Activity ctx) {

        View view = ctx.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();

        Bitmap bp = Bitmap.createBitmap(view.getDrawingCache(), 0, 0, getScreenW(ctx), getScreenH(ctx));

        view.setDrawingCacheEnabled(false);
        view.destroyDrawingCache();

        return bp;
    }

获取当前View的DrawingCache

   public static Bitmap getViewBp(View v) {
        if (null == v) {
            return null;
        }
        v.setDrawingCacheEnabled(true);
        v.buildDrawingCache();
        if (Build.VERSION.SDK_INT >= 11) {
            v.measure(MeasureSpec.makeMeasureSpec(v.getWidth(),
                    MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
                    v.getHeight(), MeasureSpec.EXACTLY));
            v.layout((int) v.getX(), (int) v.getY(),
                    (int) v.getX() + v.getMeasuredWidth(),
                    (int) v.getY() + v.getMeasuredHeight());
        } else {
            v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
        }
        Bitmap b = Bitmap.createBitmap(v.getDrawingCache(), 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());

        v.setDrawingCacheEnabled(false);
        v.destroyDrawingCache();
        return b;
    }


二:ScrollView截屏实现

在滚动视图中,我们可以利用View的ScrollTo()和ScrollBy()方法来移动画布,同时获取当前View的可视部分的DrawingCache,最后进行拼接得到其Bitmap,参考:PGSSoft/scrollscreenshot@[Github],原理图如下:

Android滚动截屏,ScrollView截屏_第1张图片


三: Padding处理

通过上面方法需要处理的就是View的paddingBottom,每次获取当前屏幕的DrawingCache的时候都会又一个PaddingBottom,拼接起来会有空白分隔,因此有了如下方法。


1.获取当前View的DrawingCache,不包括PaddingBottom

    public static Bitmap getViewBpWithoutBottom(View v) {
        if (null == v) {
            return null;
        }
        v.setDrawingCacheEnabled(true);
        v.buildDrawingCache();
        if (Build.VERSION.SDK_INT >= 11) {
            v.measure(MeasureSpec.makeMeasureSpec(v.getWidth(),
                    MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
                    v.getHeight(), MeasureSpec.EXACTLY));

            v.layout((int) v.getX(), (int) v.getY(),
                    (int) v.getX() + v.getMeasuredWidth(),
                    (int) v.getY() + v.getMeasuredHeight());
        } else {
            v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
        }

        Bitmap bp = Bitmap.createBitmap(v.getDrawingCache(), 0, 0, v.getMeasuredWidth(),
                v.getMeasuredHeight() - v.getPaddingBottom());
        v.setDrawingCacheEnabled(false);
        v.destroyDrawingCache();
        return bp;
    }

 
 

2.滚动当前视图,直到达到当前View的Bottom

    /**
     * get the bitmap of a scrollView *
     */
    public static Bitmap getViewBitmap(Context ctx, ScrollView sv) {
        if (null == sv) {
            return null;
        }
        // enable something
        sv.setVerticalScrollBarEnabled(false);
        sv.setVerticalFadingEdgeEnabled(false);
        sv.scrollTo(0, 0);
        sv.setDrawingCacheEnabled(true);
        sv.buildDrawingCache(true);
        Bitmap b = getViewBpWithoutBottom(sv);

        /**
         * vh : the height of the scrollView that is visible <BR>
         * th : the total height of the scrollView <BR>
         **/
        int vh = sv.getHeight();
        int th = sv.getChildAt(0).getHeight();

        /** the total height is more than one screen */
        if (th > vh) {
            int w = getScreenW(ctx);
            int absVh = vh - sv.getPaddingTop() - sv.getPaddingBottom();
            do {
                int restHeight = th - vh;
                Bitmap temp = null;
                if (restHeight <= absVh) {
                    sv.scrollBy(0, restHeight);
                    vh += restHeight;
                    temp = getViewBp(sv);
                } else {
                    sv.scrollBy(0, absVh);
                    vh += absVh;
                    temp = getViewBpWithoutBottom(sv);
                }
                b = mergeBitmap(vh, w, temp, 0, sv.getScrollY(), b, 0, 0);
            } while (vh < th);
        }

        // restore somthing
        sv.scrollTo(0, 0);
        sv.setVerticalScrollBarEnabled(true);
        sv.setVerticalFadingEdgeEnabled(true);
        sv.setDrawingCacheEnabled(false);
        sv.destroyDrawingCache();
        return b;
    }

3.bitmap拼接

    public static Bitmap mergeBitmap(int newImageH, int newIamgeW,
                                     Bitmap background, float backX, float backY, Bitmap foreground,
                                     float foreX, float foreY) {
        if (null == background || null == foreground) {
            return null;
        }
        // create the new blank bitmap 创建一个新的和SRC长度宽度一样的位图
        Bitmap newbmp = Bitmap.createBitmap(newIamgeW, newImageH,
                Config.RGB_565);
        Canvas cv = new Canvas(newbmp);
        // draw bg into
        cv.drawBitmap(background, backX, backY, null);
        // draw fg into
        cv.drawBitmap(foreground, foreX, foreY, null);
        // save all clip
        cv.save(Canvas.ALL_SAVE_FLAG);// 保存
        // store
        cv.restore();// 存储

        return newbmp;
    }


四: 其他屏幕相关工具

1.获取状态来高度常见方式

    /**
     * get the height of status *
     */
    public static int getStatusH(Activity ctx) {
        Rect s = new Rect();
        ctx.getWindow().getDecorView().getWindowVisibleDisplayFrame(s);
        return s.top;
    }

    /**
     * get the height of status *
     */
    public static int getStatusH(Context ctx) {
        int statusHeight = -1;
        try {
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            int height = Integer.parseInt(clazz.getField("status_bar_height")
                    .get(object).toString());
            statusHeight = ctx.getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return statusHeight;
    }

    /**
     * get the height of status *
     */
    public static int getStatusHeight(Activity activity) {
        int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
        return resourceId > 0 ? activity.getResources().getDimensionPixelSize(resourceId) : 0;
    }


2.获取标题栏高度

    /**
     * get the height of title *
     */
    public static int getTitleH(Activity ctx) {
        int contentTop = ctx.getWindow()
                .findViewById(Window.ID_ANDROID_CONTENT).getTop();
        return contentTop - getStatusH(ctx);
    }

3.获取屏幕宽高

    /**
     * get the width of screen **
     */
    public static int getScreenW(Context ctx) {
        int w = 0;
        if (Build.VERSION.SDK_INT > 13) {
            Point p = new Point();
            ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE))
                    .getDefaultDisplay().getSize(p);
            w = p.x;
        } else {
            w = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE))
                    .getDefaultDisplay().getWidth();
        }
        return w;
    }

    /**
     * get the height of screen *
     */
    public static int getScreenH(Context ctx) {
        int h = 0;
        if (Build.VERSION.SDK_INT > 13) {
            Point p = new Point();
            ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE))
                    .getDefaultDisplay().getSize(p);
            h = p.y;
        } else {
            h = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE))
                    .getDefaultDisplay().getHeight();
        }
        return h;
    }


    /**
     * 获得屏幕高度
     *
     * @param context
     * @return
     */
    public static int getScreenWidth(Context context) {
        WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.widthPixels;
    }


工具类: ScreenUtil@[Github]

使用Demo:ScreenShotActivity@[Github]

你可能感兴趣的:(android,截屏,滚动截屏,ScrollView截屏)