您好,登錄后才能下訂單哦!
怎么用android實(shí)現(xiàn)截圖和動(dòng)畫消失功能?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
整體思路
1、獲取要截圖的view
2、根據(jù)這個(gè)view創(chuàng)建Bitmap
3、保存圖片,拿到圖片路徑
4、把圖片路徑傳入自定義view(自定義view實(shí)現(xiàn)的功能:畫圓角邊框,動(dòng)畫縮小至消失)
主要用到的是ObjectAnimator屬性動(dòng)畫的縮小和平移
核心代碼
得到圖片的路徑
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);
截圖實(shí)現(xiàn)圓角邊框和動(dòng)畫消失
//實(shí)現(xiàn)截圖動(dòng)畫(添加圓角邊框) 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) { // 避免截圖成功時(shí)出現(xiàn)短暫的全屏白色背景 thumb.setImageDrawable(resource); } if (anim) { anim(thumb, true); } return false; } }).into(thumb); //啟動(dòng)延時(shí)關(guān)閉截圖(顯示5秒消失截圖) startTick(true);
動(dòng)畫設(shè)置
/** * 動(dòng)畫設(shè)置 * @param view * @param start */ private void anim(final ImageView view, boolean start) { if (!start) { if (getChildCount() > 0) { // 快速點(diǎn)擊截圖時(shí),上一次添加的子視圖尚未移除,需重置視圖 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動(dòng)畫 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); //以當(dāng)前view為中心,x軸右為正,左為負(fù);y軸下為正,上為負(fù) 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); //設(shè)置速度 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); //設(shè)置截圖之后的寬度,高度按照比例設(shè)置 mFinalW = (int) DisplayUtil.dip2px(getContext(), 90); mFinalH = (int) ((float) mFinalW * h) / w; if (!anim) { //設(shè)置邊框 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 { //設(shè)置邊框 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) { // 避免截圖成功時(shí)出現(xiàn)短暫的全屏白色背景 thumb.setImageDrawable(resource); } if (anim) { anim(thumb, true); } return false; } }).into(thumb); //啟動(dòng)延時(shí)關(guān)閉截圖(顯示5秒消失截圖) startTick(true); } }); } /** * 動(dòng)畫設(shè)置 * @param view * @param start */ private void anim(final ImageView view, boolean start) { if (!start) { if (getChildCount() > 0) { // 快速點(diǎn)擊截圖時(shí),上一次添加的子視圖尚未移除,需重置視圖 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動(dòng)畫 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); //以當(dāng)前view為中心,x軸右為正,左為負(fù);y軸下為正,上為負(fù) 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); //設(shè)置速度 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; /** * 構(gòu)造函數(shù) 默認(rèn)圓角半徑 4dp * * @param context Context */ public GlideRoundTransform(Context context) { this(context, 4); } /** * 構(gòu)造函數(shù) * * @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(); } }); } /** * 處理截屏的業(yè)務(wù) */ private void handleScreenShot() { if (!PermissionUtil.isHasSDCardWritePermission(this)) { Toast.makeText(ScreenShotActivity1.this, "沒有權(quán)限", Toast.LENGTH_SHORT).show(); PermissionUtil.requestSDCardWrite(this); return; } if (!MemoryUtils.hasEnoughMemory(MemoryUtils.MIN_MEMORY)) { Toast.makeText(ScreenShotActivity1.this, "內(nèi)存不足,截圖失敗", 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 { /** * 請(qǐng)求地理位置 * * @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; } /** * 判斷是否有文件讀寫的權(quán)限 * * @param context * @return */ public static boolean isHasSDCardWritePermission(Context context) { return ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; } /** * 文件權(quán)限讀寫 * * @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; /** * 判斷有沒足夠內(nèi)存截圖 * * @param size * @return */ public static boolean hasEnoughMemory(int size) { //最大內(nèi)存 long maxMemory = Runtime.getRuntime().maxMemory(); //分配的可用內(nèi)存 long freeMemory = Runtime.getRuntime().freeMemory(); //已用內(nèi)存 long usedMemory = Runtime.getRuntime().totalMemory() - freeMemory; //剩下可使用的內(nèi)存 long canUseMemory = maxMemory - usedMemory; Log.d("Memory", "hasEnoughMemory: " + "maxMemory = " + maxMemory + ", freeMemory = " + freeMemory + ", usedMemory = " + usedMemory + ", canUseMemory = " + canUseMemory); if (canUseMemory >= size) { return true; } return false; } }
關(guān)于怎么用android實(shí)現(xiàn)截圖和動(dòng)畫消失功能問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。