안 드 로 이 드 캡 처 및 애니메이션 사라 짐 효과 에 대한 자세 한 설명
25402 단어 android캡 처애니메이션 사라 짐
전체적인 사고 방식.
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;
}
}
총결산안 드 로 이 드 가 캡 처 를 실현 하고 애니메이션 이 사라 진 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 안 드 로 이 드 가 캡 처 를 실현 하고 애니메이션 이 사라 진 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 저 희 를 많이 사랑 해 주세요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.