整体思路
1、获取要截图的view 2、根据这个view创建Bitmap 3、保存图片,拿到图片路径 4、把图片路径传入自定义view(自定义view实现的功能:画圆角边框,动画缩小至消失) 主要用到的是ObjectAnimator属性动画的缩小和平移
核心代码
得到图片的路径
private String getFilePath() {
Bitmap bitmap = createViewBitmap(picImg);
if (bitmap != null) {
try {
// 首先保存图片
String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "HIS";
File appDir = new File(storePath);
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
sendBroadcast(intent);
return file.getAbsolutePath();
} catch (Exception e) {
return null;
}
} else {
return null;
}
}
public Bitmap createViewBitmap(View v) {
Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
v.draw(canvas);
return bitmap;
}
把图片路径传入自定义view
String filePath = getFilePath();
mDisplayScreenshotSnv.setVisibility(View.GONE);
mDisplayScreenshotSnv.setPath(filePath, picImg.getMeasuredWidth(), picImg.getMeasuredHeight(), true);
mDisplayScreenshotSnv.setVisibility(View.VISIBLE);
截图实现圆角边框和动画消失
//实现截图动画(添加圆角边框)
Glide.with(getContext())
.load(new File(path))
.transform(new CenterCrop(getContext()), new GlideRoundTransform(getContext(), radius))
.crossFade()
.listener(new RequestListener<File, GlideDrawable () {
@Override
public boolean onException(Exception e, File model, Target<GlideDrawable target, boolean isFirstResource) {
if (anim) {
anim(thumb, true);
}
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, File model, Target<GlideDrawable target, boolean isFromMemoryCache, boolean isFirstResource) {
if (thumb.getDrawable() == null) {
// 避免截图成功时出现短暂的全屏白色背景
thumb.setImageDrawable(resource);
}
if (anim) {
anim(thumb, true);
}
return false;
}
}).into(thumb);
//启动延时关闭截图(显示5秒消失截图)
startTick(true);
动画设置
/**
* 动画设置
* @param view
* @param start
*/
private void anim(final ImageView view, boolean start) {
if (!start) {
if (getChildCount() 0) {
// 快速点击截图时,上一次添加的子视图尚未移除,需重置视图
resetView();
}
setScaleX(1f);
setScaleY(1f);
setTranslationX(0f);
setTranslationY(0f);
clearAnimation();
if (mScaleXAnim != null) {
mScaleXAnim.cancel();
mScaleXAnim = null;
}
if (mScaleYAnim != null) {
mScaleYAnim.cancel();
mScaleYAnim = null;
}
if (mTranslationXAnim != null) {
mTranslationXAnim.cancel();
mTranslationXAnim = null;
}
if (mTranslationYAnim != null) {
mTranslationYAnim.cancel();
mTranslationYAnim = null;
}
return;
}
view.post(new Runnable() {
@Override
public void run() {
if (!view.isAttachedToWindow()) {
// 子视图已被移除
return;
}
setCardBackgroundColor(Color.WHITE);
//等待cross fade动画
float margins = DisplayUtil.dip2px(getContext(), 10);
float scaleToX = (float) mFinalW / getMeasuredWidth();
float scaleToY = (float) mFinalH / getMeasuredHeight();
float translateToX = -(getMeasuredWidth() / 2f - (mFinalW / 2 + margins));
float translateToY = getMeasuredHeight() / 2f - (mFinalH / 2f + margins);
//以当前view为中心,x轴右为正,左为负;y轴下为正,上为负
mScaleXAnim = ObjectAnimator.ofFloat(ScreenshotNotifyView.this, "scaleX", 1.0f, scaleToX);
mScaleYAnim = ObjectAnimator.ofFloat(ScreenshotNotifyView.this, "scaleY", 1.0f, scaleToY);
mTranslationXAnim = ObjectAnimator.ofFloat(ScreenshotNotifyView.this, "translationX", 1.0f, translateToX);
mTranslationYAnim = ObjectAnimator.ofFloat(ScreenshotNotifyView.this, "translationY", 1.0f, translateToY);
//设置速度
mScaleXAnim.setDuration(500);
mScaleYAnim.setDuration(500);
mTranslationXAnim.setDuration(500);
mTranslationYAnim.setDuration(500);
//缩放
mScaleXAnim.start();
mScaleYAnim.start();
//平移
mTranslationXAnim.start();
mTranslationYAnim.start();
setEnabled(false);
mScaleXAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
setEnabled(true);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
setEnabled(true);
setClickable(true);
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
}
});
}
});
}
完整代码
ScreenshotNotifyView.java
package com.lyw.myproject.widget;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.lyw.myproject.screenshot.GlideRoundTransform;
import com.lyw.myproject.utils.DisplayUtil;
import java.io.File;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
public class ScreenshotNotifyView extends CardView {
private int mFinalW;
private int mFinalH;
private Handler mHandler;
private ObjectAnimator mScaleXAnim = null;
private ObjectAnimator mScaleYAnim = null;
private ObjectAnimator mTranslationXAnim = null;
private ObjectAnimator mTranslationYAnim = null;
public ScreenshotNotifyView(@NonNull Context context) {
super(context);
init(context);
}
public ScreenshotNotifyView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ScreenshotNotifyView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@Override
public void setVisibility(int visibility) {
super.setVisibility(visibility);
if (visibility == GONE) {
resetView();
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
anim(null, false);
startTick(false);
}
private void init(Context context) {
mHandler = new Handler(Looper.getMainLooper());
setCardElevation(0);
}
public void setPath(final String path, int w, int h, final boolean anim) {
setClickable(false);
anim(null, false);
final ImageView thumb = new ImageView(getContext());
FrameLayout.LayoutParams thumbParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams();
int padding = (int) DisplayUtil.dip2px(getContext(), 2);
int margins = (int) DisplayUtil.dip2px(getContext(), 8);
//设置截图之后的宽度,高度按照比例设置
mFinalW = (int) DisplayUtil.dip2px(getContext(), 90);
mFinalH = (int) ((float) mFinalW * h) / w;
if (!anim) {
//设置边框
params.setMargins(margins, margins, margins, margins);
margins = (int) DisplayUtil.dip2px(getContext(), 2);
params.width = mFinalW + margins * 2;
params.height = mFinalH + margins * 2;
params.gravity = Gravity.START | Gravity.BOTTOM;
thumbParams.width = mFinalW;
thumbParams.height = mFinalH;
thumbParams.gravity = Gravity.CENTER;
setLayoutParams(params);
requestLayout();
} else {
//设置边框
thumbParams.setMargins(margins, margins, margins, margins);
params.setMargins(0, 0, 0, 0);
params.width = FrameLayout.LayoutParams.MATCH_PARENT;
params.height = FrameLayout.LayoutParams.MATCH_PARENT;
setLayoutParams(params);
requestLayout();
}
thumb.setScaleType(ImageView.ScaleType.FIT_XY);
thumb.setLayoutParams(thumbParams);
addView(thumb);
post(new Runnable() {
@Override
public void run() {
float scale = (float) mFinalW / getMeasuredWidth();
int radius = 5;
if (anim) {
radius = (int) (5f / scale);
}
setRadius((int) DisplayUtil.dip2px(getContext(), radius));
//显示截图(添加圆角)
Glide.with(getContext())
.load(new File(path))
.transform(new CenterCrop(getContext()), new GlideRoundTransform(getContext(), radius))
.crossFade()
.listener(new RequestListener<File, GlideDrawable () {
@Override
public boolean onException(Exception e, File model, Target<GlideDrawable target, boolean isFirstResource) {
if (anim) {
anim(thumb, true);
}
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, File model, Target<GlideDrawable target, boolean isFromMemoryCache, boolean isFirstResource) {
if (thumb.getDrawable() == null) {
// 避免截图成功时出现短暂的全屏白色背景
thumb.setImageDrawable(resource);
}
if (anim) {
anim(thumb, true);
}
return false;
}
}).into(thumb);
//启动延时关闭截图(显示5秒消失截图)
startTick(true);
}
});
}
/**
* 动画设置
* @param view
* @param start
*/
private void anim(final ImageView view, boolean start) {
if (!start) {
if (getChildCount() 0) {
// 快速点击截图时,上一次添加的子视图尚未移除,需重置视图
resetView();
}
setScaleX(1f);
setScaleY(1f);
setTranslationX(0f);
setTranslationY(0f);
clearAnimation();
if (mScaleXAnim != null) {
mScaleXAnim.cancel();
mScaleXAnim = null;
}
if (mScaleYAnim != null) {
mScaleYAnim.cancel();
mScaleYAnim = null;
}
if (mTranslationXAnim != null) {
mTranslationXAnim.cancel();
mTranslationXAnim = null;
}
if (mTranslationYAnim != null) {
mTranslationYAnim.cancel();
mTranslationYAnim = null;
}
return;
}
view.post(new Runnable() {
@Override
public void run() {
if (!view.isAttachedToWindow()) {
// 子视图已被移除
return;
}
setCardBackgroundColor(Color.WHITE);
//等待cross fade动画
float margins = DisplayUtil.dip2px(getContext(), 10);
float scaleToX = (float) mFinalW / getMeasuredWidth();
float scaleToY = (float) mFinalH / getMeasuredHeight();
float translateToX = -(getMeasuredWidth() / 2f - (mFinalW / 2 + margins));
float translateToY = getMeasuredHeight() / 2f - (mFinalH / 2f + margins);
//以当前view为中心,x轴右为正,左为负;y轴下为正,上为负
mScaleXAnim = ObjectAnimator.ofFloat(ScreenshotNotifyView.this, "scaleX", 1.0f, scaleToX);
mScaleYAnim = ObjectAnimator.ofFloat(ScreenshotNotifyView.this, "scaleY", 1.0f, scaleToY);
mTranslationXAnim = ObjectAnimator.ofFloat(ScreenshotNotifyView.this, "translationX", 1.0f, translateToX);
mTranslationYAnim = ObjectAnimator.ofFloat(ScreenshotNotifyView.this, "translationY", 1.0f, translateToY);
//设置速度
mScaleXAnim.setDuration(500);
mScaleYAnim.setDuration(500);
mTranslationXAnim.setDuration(500);
mTranslationYAnim.setDuration(500);
//缩放
mScaleXAnim.start();
mScaleYAnim.start();
//平移
mTranslationXAnim.start();
mTranslationYAnim.start();
setEnabled(false);
mScaleXAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
setEnabled(true);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
setEnabled(true);
setClickable(true);
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
}
});
}
});
}
private void resetView() {
setCardBackgroundColor(Color.TRANSPARENT);
removeAllViews();
startTick(false);
}
private void startTick(boolean start) {
if (!start) {
mHandler.removeCallbacksAndMessages(null);
return;
}
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
setVisibility(GONE);
}
}, 5 * 1000);
}
}
GlideRoundTransform.java
package com.lyw.myproject.screenshot;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
/**
* Created on 2018/12/26.
*
* @author lyw
**/
public class GlideRoundTransform extends BitmapTransformation {
private static float radius = 0f;
/**
* 构造函数 默认圆角半径 4dp
*
* @param context Context
*/
public GlideRoundTransform(Context context) {
this(context, 4);
}
/**
* 构造函数
*
* @param context Context
* @param dp 圆角半径
*/
public GlideRoundTransform(Context context, int dp) {
super(context);
radius = Resources.getSystem().getDisplayMetrics().density * dp;
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return roundCrop(pool, toTransform);
}
private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {
if (source == null) {
return null;
}
Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rectF, radius, radius, paint);
return result;
}
@Override
public String getId() {
return getClass().getName() + Math.round(radius);
}
}
activity_screen_shot1.xml
<?xml version="1.0" encoding="utf-8"?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
<ImageView
android:id="@+id/pic_iv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@mipmap/picture" /
<com.lyw.myproject.widget.ScreenshotNotifyView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/display_screenshot_snv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:cardBackgroundColor="@color/src_trans" /
</FrameLayout
<Button
android:id="@+id/screen_btn"
android:text="截图"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/
</LinearLayout
ScreenShotActivity1.java
package com.lyw.myproject.screenshot;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.lyw.myproject.BaseActivity;
import com.lyw.myproject.R;
import com.lyw.myproject.utils.LoadingLayout;
import com.lyw.myproject.utils.MemoryUtils;
import com.lyw.myproject.utils.PermissionUtil;
import com.lyw.myproject.widget.ScreenshotNotifyView;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import androidx.annotation.Nullable;
/**
* 功能描述:截图
*/
public class ScreenShotActivity1 extends BaseActivity {
private ImageView picImg;
private Button screenBtn;
private ScreenshotNotifyView mDisplayScreenshotSnv;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_shot1);
initView();
initEvent();
}
private void initView() {
picImg = (ImageView) findViewById(R.id.pic_iv);
mDisplayScreenshotSnv = (ScreenshotNotifyView) findViewById(R.id.display_screenshot_snv);
screenBtn = (Button) findViewById(R.id.screen_btn);
}
private void initEvent() {
screenBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleScreenShot();
}
});
}
/**
* 处理截屏的业务
*/
private void handleScreenShot() {
if (!PermissionUtil.isHasSDCardWritePermission(this)) {
Toast.makeText(ScreenShotActivity1.this, "没有权限", Toast.LENGTH_SHORT).show();
PermissionUtil.requestSDCardWrite(this);
return;
}
if (!MemoryUtils.hasEnoughMemory(MemoryUtils.MIN_MEMORY)) {
Toast.makeText(ScreenShotActivity1.this, "内存不足,截图失败", Toast.LENGTH_SHORT).show();
return;
}
String filePath = getFilePath();
mDisplayScreenshotSnv.setVisibility(View.GONE);
mDisplayScreenshotSnv.setPath(filePath, picImg.getMeasuredWidth(), picImg.getMeasuredHeight(), true);
mDisplayScreenshotSnv.setVisibility(View.VISIBLE);
}
private String getFilePath() {
Bitmap bitmap = createViewBitmap(picImg);
if (bitmap != null) {
try {
// 首先保存图片
String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "HIS";
File appDir = new File(storePath);
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
sendBroadcast(intent);
return file.getAbsolutePath();
} catch (Exception e) {
return null;
}
} else {
return null;
}
}
public Bitmap createViewBitmap(View v) {
Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
v.draw(canvas);
return bitmap;
}
}
PermissionUtil.java
package com.lyw.myproject.utils;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;
public class PermissionUtil {
/**
* 请求地理位置
*
* @param context
*/
public static void requestLocationPermission(Context context) {
if (Build.VERSION.SDK_INT = 23) {
if (!isHasLocationPermission(context)) {
ActivityCompat.requestPermissions((Activity) context, PermissionManager.PERMISSION_LOCATION, PermissionManager.REQUEST_LOCATION);
}
}
}
/**
* 判断是否有地理位置
*
* @param context
* @return
*/
public static boolean isHasLocationPermission(Context context) {
return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
/**
* 判断是否有文件读写的权限
*
* @param context
* @return
*/
public static boolean isHasSDCardWritePermission(Context context) {
return ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}
/**
* 文件权限读写
*
* @param context
*/
public static void requestSDCardWrite(Context context) {
if (Build.VERSION.SDK_INT = 23) {
if (!isHasSDCardWritePermission(context)) {
ActivityCompat.requestPermissions((Activity) context, PermissionManager.PERMISSION_SD_WRITE, PermissionManager.REQUEST_SD_WRITE);
}
}
}
}
MemoryUtils.java
package com.lyw.myproject.utils;
import android.util.Log;
public class MemoryUtils {
public static final int MIN_MEMORY = 50 * 1024 * 1024;
/**
* 判断有没足够内存截图
*
* @param size
* @return
*/
public static boolean hasEnoughMemory(int size) {
//最大内存
long maxMemory = Runtime.getRuntime().maxMemory();
//分配的可用内存
long freeMemory = Runtime.getRuntime().freeMemory();
//已用内存
long usedMemory = Runtime.getRuntime().totalMemory() - freeMemory;
//剩下可使用的内存
long canUseMemory = maxMemory - usedMemory;
Log.d("Memory", "hasEnoughMemory: " +
"maxMemory = " + maxMemory +
", freeMemory = " + freeMemory +
", usedMemory = " + usedMemory +
", canUseMemory = " + canUseMemory);
if (canUseMemory = size) {
return true;
}
return false;
}
}
总结
到此这篇关于android实现截图并动画消失的文章就介绍到这了,更多相关android实现截图并动画消失内容请搜索ZaLou.Cn以前的文章或继续浏览下面的相关文章希望大家以后多多支持ZaLou.Cn!