实现手机截屏效果,保存截屏图片

一、准备一张图片

拷贝screenshot_panel.9.png放在目录drawable-xhdpi下

二、activity_main.xml

代码如下:

<RelativeLayout xmlns:android=""xmlns:tools=""android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello_world" /><Buttonandroid:id="@+id/main_btn"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Shot"android:layout_alignParentBottom="true"/></RelativeLayout>三、新建xml文件<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android=""android:layout_width="match_parent"android:layout_height="match_parent"><ImageView android:id="@+id/global_screenshot_background"android:layout_width="match_parent"android:layout_height="match_parent"android:src="@android:color/black"android:visibility="gone" /><ImageView android:id="@+id/global_screenshot"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:background="@drawable/screenshot_panel"android:visibility="gone"android:adjustViewBounds="true" /><ImageView android:id="@+id/global_screenshot_flash"android:layout_width="match_parent"android:layout_height="match_parent"android:src="@android:color/white"android:visibility="gone" /></FrameLayout>四、在dimens.xml添加一项 <dimen name="global_screenshot_bg_padding">20dp</dimen>五、后台代码

1)SurfaceControl.java

import android.graphics.Bitmap;import android.view.View;public class SurfaceControl {public static Bitmap screenshot(View view) {view.setDrawingCacheEnabled(true);view.buildDrawingCache();Bitmap bmp = view.getDrawingCache();return bmp;}}2)GlobalScreenShot.java代码如下,,其中SavePicture方法有保存截图的路径import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.AnimatorSet;import android.animation.ValueAnimator;import android.animation.ValueAnimator.AnimatorUpdateListener;import android.content.Context;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.Matrix;import android.graphics.PixelFormat;import android.graphics.PointF;import android.media.MediaActionSound;import android.net.Uri;import android.os.Environment;import android.util.DisplayMetrics;import android.util.Log;import android.view.Display;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.view.animation.Interpolator;import android.widget.ImageView;import android.widget.Toast;/** * POD used in the AsyncTask which saves an image in the background. */class SaveImageInBackgroundData {Context context;Bitmap image;Uri imageUri;Runnable finisher;int iconSize;int result;void clearImage() {image = null;imageUri = null;iconSize = 0;}void clearContext() {context = null;}}/** * TODO: * – Performance when over gl surfaces? Ie. Gallery * – what do we say in the Toast? Which icon do we get if the user uses another * type of gallery? */class GlobalScreenshot {private static final String TAG = "GlobalScreenshot";private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;private static final int SCREENSHOT_DROP_IN_DURATION = 430;private static final int SCREENSHOT_DROP_OUT_DELAY = 500;private static final int SCREENSHOT_DROP_OUT_DURATION = 430;private static final int SCREENSHOT_DROP_OUT_SCALE_DURATION = 370;private static final int SCREENSHOT_FAST_DROP_OUT_DURATION = 320;private static final float BACKGROUND_ALPHA = 0.5f;private static final float SCREENSHOT_SCALE = 1f;private static final float SCREENSHOT_DROP_IN_MIN_SCALE = SCREENSHOT_SCALE * 0.725f;private static final float SCREENSHOT_DROP_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.45f;private static final float SCREENSHOT_FAST_DROP_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.6f;private static final float SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET = 0f;private Context mContext;private WindowManager mWindowManager;private WindowManager.LayoutParams mWindowLayoutParams;private Display mDisplay;private DisplayMetrics mDisplayMetrics;private Bitmap mScreenBitmap;private View mScreenshotLayout;private ImageView mBackgroundView;private ImageView mScreenshotView;private ImageView mScreenshotFlash;private AnimatorSet mScreenshotAnimation;private float mBgPadding;private float mBgPaddingScale;private MediaActionSound mCameraSound;/*** @param context everything needs a context :(*/public GlobalScreenshot(Context context) {Resources r = context.getResources();mContext = context;LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);// Inflate the screenshot layoutmScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null);mBackgroundView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_background);mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot);mScreenshotFlash = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_flash);mScreenshotLayout.setFocusable(true);mScreenshotLayout.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// Intercept and ignore all touch eventsreturn true;}});// Setup the window that we are going to usemWindowLayoutParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,WindowManager.LayoutParams.FLAG_FULLSCREEN| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,PixelFormat.TRANSLUCENT);mWindowLayoutParams.setTitle("ScreenshotAnimation");mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);mDisplay = mWindowManager.getDefaultDisplay();mDisplayMetrics = new DisplayMetrics();mDisplay.getRealMetrics(mDisplayMetrics);// Scale has to account for both sides of the bgmBgPadding = (float) r.getDimensionPixelSize(R.dimen.global_screenshot_bg_padding);mBgPaddingScale = mBgPadding / mDisplayMetrics.widthPixels;// Setup the Camera shutter soundmCameraSound = new MediaActionSound();mCameraSound.load(MediaActionSound.SHUTTER_CLICK);}/*** Takes a screenshot of the current display and shows an animation.*/void takeScreenshot(View view, Runnable finisher, boolean statusBarVisible, boolean navBarVisible) {// Take the screenshotLog.d("debug","takeScreenshot start");mScreenBitmap = SurfaceControl.screenshot(view);Log.d("debug","takeScreenshot 1");if (mScreenBitmap == null) {notifyScreenshotError(mContext);finisher.run();return;}// OptimizationsmScreenBitmap.setHasAlpha(false);mScreenBitmap.prepareToDraw();Log.d("debug","takeScreenshot 2");Log.d("debug","takeScreenshot 3");// Start the post-screenshot animationstartAnimation(finisher, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels,statusBarVisible, navBarVisible);Log.d("debug","takeScreenshot end");}private void SavePicture(){Log.d("debug","SavePicture 1");mScreenshotView.setDrawingCacheEnabled(true);Log.d("debug","SavePicture 2");Bitmap obmp = Bitmap.createBitmap(mScreenshotView.getDrawingCache());Log.d("debug","SavePicture 3");if (obmp != null) {// 图片存储路径String SavePath = getSDCardPath() + "/test/ScreenImages";// 保存BitmapLog.d("debug","SavePath = "+SavePath);try {File path = new File(SavePath);// 文件String filepath = SavePath + "/Screen_1.png";Log.d("debug","filepath = "+filepath);File file = new File(filepath);if (!path.exists()) {Log.d("debug","path is not exists");path.mkdirs();}if (!file.exists()) {Log.d("debug","file create new ");file.createNewFile();}FileOutputStream fos = null;fos = new FileOutputStream(file);if (null != fos) {obmp.compress(Bitmap.CompressFormat.PNG, 90, fos);fos.flush();fos.close();Log.d("debug","save ok");}} catch (Exception e) {e.printStackTrace();}}}/** * 获取SDCard的目录路径功能 * * @return */private String getSDCardPath() {File sdcardDir = null;// 判断SDCard是否存在boolean sdcardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);if (sdcardExist) {sdcardDir = Environment.getExternalStorageDirectory();}return sdcardDir.toString();}/*** Starts the animation after taking the screenshot*/private void startAnimation(final Runnable finisher, int w, int h, boolean statusBarVisible,boolean navBarVisible) {// Add the view for the animationmScreenshotView.setImageBitmap(mScreenBitmap);mScreenshotLayout.requestFocus();// Setup the animation with the screenshot just takenif (mScreenshotAnimation != null) {mScreenshotAnimation.end();mScreenshotAnimation.removeAllListeners();}mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);ValueAnimator screenshotDropInAnim = createScreenshotDropInAnimation();ValueAnimator screenshotFadeOutAnim = createScreenshotDropOutAnimation(w, h,statusBarVisible, navBarVisible);mScreenshotAnimation = new AnimatorSet();mScreenshotAnimation.playSequentially(screenshotDropInAnim, screenshotFadeOutAnim);mScreenshotAnimation.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {// Save the screenshot once we have a bit of time nowsaveScreenshotInWorkerThread(finisher);mWindowManager.removeView(mScreenshotLayout);SavePicture();// Clear any references to the bitmapmScreenBitmap = null;mScreenshotView.setImageBitmap(null);}});mScreenshotLayout.post(new Runnable() {@Overridepublic void run() {// Play the shutter sound to notify that we've taken a screenshotmCameraSound.play(MediaActionSound.SHUTTER_CLICK);mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, null);mScreenshotView.buildLayer();mScreenshotAnimation.start();}});}private ValueAnimator createScreenshotDropInAnimation() {final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION)/ SCREENSHOT_DROP_IN_DURATION);final float flashDurationPct = 2f * flashPeakDurationPct;final Interpolator flashAlphaInterpolator = new Interpolator() {@Overridepublic float getInterpolation(float x) {// Flash the flash view in and out quicklyif (x <= flashDurationPct) {return (float) Math.sin(Math.PI * (x / flashDurationPct));}return 0;}};final Interpolator scaleInterpolator = new Interpolator() {@Overridepublic float getInterpolation(float x) {// We start scaling when the flash is at it's peakif (x < flashPeakDurationPct) {return 0;}return (x – flashDurationPct) / (1f – flashDurationPct);}};ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);anim.setDuration(SCREENSHOT_DROP_IN_DURATION);anim.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationStart(Animator animation) {mBackgroundView.setAlpha(0f);mBackgroundView.setVisibility(View.VISIBLE);mScreenshotView.setAlpha(0f);mScreenshotView.setTranslationX(0f);mScreenshotView.setTranslationY(0f);mScreenshotView.setScaleX(SCREENSHOT_SCALE + mBgPaddingScale);mScreenshotView.setScaleY(SCREENSHOT_SCALE + mBgPaddingScale);mScreenshotView.setVisibility(View.VISIBLE);mScreenshotFlash.setAlpha(0f);mScreenshotFlash.setVisibility(View.VISIBLE);}@Overridepublic void onAnimationEnd(android.animation.Animator animation) {mScreenshotFlash.setVisibility(View.GONE);}});anim.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float t = (Float) animation.getAnimatedValue();float scaleT = (SCREENSHOT_SCALE + mBgPaddingScale)- scaleInterpolator.getInterpolation(t)* (SCREENSHOT_SCALE – SCREENSHOT_DROP_IN_MIN_SCALE);mBackgroundView.setAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);mScreenshotView.setAlpha(t);mScreenshotView.setScaleX(scaleT);mScreenshotView.setScaleY(scaleT);mScreenshotFlash.setAlpha(flashAlphaInterpolator.getInterpolation(t));}});return anim;}private ValueAnimator createScreenshotDropOutAnimation(int w, int h, boolean statusBarVisible,boolean navBarVisible) {ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);anim.setStartDelay(SCREENSHOT_DROP_OUT_DELAY);anim.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {mBackgroundView.setVisibility(View.GONE);mScreenshotView.setVisibility(View.GONE);mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null);}});if (!statusBarVisible || !navBarVisible) {// There is no status bar/nav bar, so just fade the screenshot away in placeanim.setDuration(SCREENSHOT_FAST_DROP_OUT_DURATION);anim.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float t = (Float) animation.getAnimatedValue();float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)- t * (SCREENSHOT_DROP_IN_MIN_SCALE – SCREENSHOT_FAST_DROP_OUT_MIN_SCALE);mBackgroundView.setAlpha((1f – t) * BACKGROUND_ALPHA);mScreenshotView.setAlpha(1f – t);mScreenshotView.setScaleX(scaleT);mScreenshotView.setScaleY(scaleT);}});} else {// In the case where there is a status bar, animate to the origin of the bar (top-left)final float scaleDurationPct = (float) SCREENSHOT_DROP_OUT_SCALE_DURATION/ SCREENSHOT_DROP_OUT_DURATION;final Interpolator scaleInterpolator = new Interpolator() {@Overridepublic float getInterpolation(float x) {if (x < scaleDurationPct) {// Decelerate, and scale the input accordinglyreturn (float) (1f – Math.pow(1f – (x / scaleDurationPct), 2f));}return 1f;}};// Determine the bounds of how to scalefloat halfScreenWidth = (w – 2f * mBgPadding) / 2f;float halfScreenHeight = (h – 2f * mBgPadding) / 2f;final float offsetPct = SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET;final PointF finalPos = new PointF(-halfScreenWidth + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenWidth,-halfScreenHeight + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenHeight);// Animate the screenshot to the status baranim.setDuration(SCREENSHOT_DROP_OUT_DURATION);anim.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float t = (Float) animation.getAnimatedValue();float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)- scaleInterpolator.getInterpolation(t)* (SCREENSHOT_DROP_IN_MIN_SCALE – SCREENSHOT_DROP_OUT_MIN_SCALE);mBackgroundView.setAlpha((1f – t) * BACKGROUND_ALPHA);mScreenshotView.setAlpha(1f – scaleInterpolator.getInterpolation(t));mScreenshotView.setScaleX(scaleT);mScreenshotView.setScaleY(scaleT);mScreenshotView.setTranslationX(t * finalPos.x);mScreenshotView.setTranslationY(t * finalPos.y);}});}return anim;}private void notifyScreenshotError(Context context) {}private void saveScreenshotInWorkerThread(Runnable runnable) {}}如果雨后还是雨,如果忧伤过后还是忧伤,

实现手机截屏效果,保存截屏图片

相关文章:

你感兴趣的文章:

标签云: