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;
 }
}

总结

到此这篇关于android实现截图并动画消失的文章就介绍到这了,更多相关android实现截图并动画消失内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • android webView截图的4种方法

    android 在webView里面截图大概有四种方式,具体内容如下 1.获取到DecorView然后将DecorView转换成bitmap然后写入到文件里面. View view = getWindow().getDecorView(); Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitma

  • Android积分签到上移消失动画效果

    还记得以前在某云的时候,有次需求是一个积分签到,要求点击签到按钮然后有一个动画效果,比如+30积分然后慢慢往上移动在消失.那会不会做就想着改下需求,直接去掉了动画效果,而今时隔很久又遇到同样的问题,比较蛋疼的是我清楚记得当时做过这个功能,但是自己没有做出来,当然现在做还是不会.自己当年省写的代码含泪也要补上.这次吸取教训,实现这个效果. 大致思路:动画部分,由一个垂直的平移和一个透明度变化的两个动画组成.然后通过AnimationSet将两个动画添加到集合,然后开始播放动画. 更新UI部分,用的

  • Android属性动画实现图片从左到右逐渐消失

    前言:dp/dip代表独立像素,dpi代表屏幕每英寸像素点的个数,px与dp的转换公式为: px = dp *(dpi / 160) 一.效果图 二.源代码 AnimationActivity: package com.example.duoyi.clientaidl; import android.animation.Animator; import android.animation.ObjectAnimator; import android.support.annotation.NonN

  • Android使用WebView实现截图分享功能

    在APP项目的开发过程中,经常会用到分享图片的功能,有时候还需要根据当前用户信息获取指定的分享图片,比如要求在用户分享图中显示用户名.Uid.用户头像等信息.想到的实现方法主要有两点: 1.通过android SDK自带的Canvas方法进行绘制. 2.通过webView实现客户端与H5交互,然后将H5界面做截图处理. 本文主要介绍第二种方式的实现过程,第一种方式的实现方法,后续有时间会在博客中做说明,下面开始本文内容. 首先确定我们要实现的逻辑: 1.客户端与H5的交互,客户端将用户信息(用户

  • android实现手机截屏并保存截图功能

    本文实例为大家分享了android实现手机截屏并保存截图功能的具体代码,供大家参考,具体内容如下 一.准备一张图片 拷贝screenshot_panel.9.png放在目录drawable-xhdpi下 二.activity_main.xml 代码如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.androi

  • Android实现自动截图脚本

    做开发的总会碰到测试或者项目经理问你要某个界面截图的情况,用手机的快捷键截图再上传效率不高,又不太想用手机助手(怕全家桶),便打起Android的ADB命令的主意.adb指令中screencap指令就是截图方法,再通过pull拉取到指定文件夹即可. 这边我对不同的操作系统都进行了相应的整理和使用.windows下为批处理程序,mac下为shell可执行脚本程序. 需注意,脚本使用,都需要先在桌面上新建AndroidScreen文件夹,然后电脑同时只可以连接一台手机(当然这些也都可以完善). Wi

  • android实现截图并动画消失效果的思路详解

    整体思路 1.获取要截图的view 2.根据这个view创建Bitmap 3.保存图片,拿到图片路径 4.把图片路径传入自定义view(自定义view实现的功能:画圆角边框,动画缩小至消失) 主要用到的是ObjectAnimator属性动画的缩小和平移 核心代码 得到图片的路径 private String getFilePath() { Bitmap bitmap = createViewBitmap(picImg); if (bitmap != null) { try { // 首先保存图片

  • 基于Android studio3.6的JNI教程之helloworld思路详解

    jdk环境变量配置: path中增加下面2个路径,也就是android studio的路径,android有自带的jdk. E:\Android\Android Studio\jre\bin E:\Android\Android Studio\bin 新建工程: 一定要选择Native c++类型,最后要选c++11支持. SDK设置: File->Settings File->Project Structure 首先确定工程的目录结构,然后尝试运行一下工程,使用模拟器,确保工程没问题, 在M

  • jQuery动态添加.active 实现导航效果代码思路详解

     代码思路: 页面4: 页面5: 代码思路: 通过jq获取你打开页面的链接  window.location.pathname: 在HTML中给自己的li加入一个ID id的命名与网址链接中的href相同 通过jq包含方法找到相对应的li给他加入active类名 然后..就没有然后了... jq代码: $(function () { var li = $(".title_ul").children("li"); for (var i = 0; i < li.l

  • Qt实现界面滑动切换效果的思路详解

    目录 一.Qt实现界面滑动切换效果 二. 设计思路 三.主要函数讲解 四.源代码解析 4.1 初始化界面 4.2 上一页滑动效果 4.3  下一页滑动效果 4.4 动画结束处理 五.源码地址 一.Qt实现界面滑动切换效果 效果如下图,滑动效果移动上下屏幕. 二. 设计思路 利用QStackWidget将页面存储起来,因为页面比较少,因此我直接将所有的页面存储在QStachWidget中,如果页面相对较多,可以使用使用使渲染的方式. 然后使用show函数同时展示两个页面的内容,这个很重要,如果使用

  • Android TextView渐变颜色和方向及动画效果的设置详解

    GradientTextView Github点我 一个非常好用的库,使用kotlin实现,用于设置TexView的字体 渐变颜色.渐变方向 和 动画效果 添加依赖 之前仓库发布在 jcenter,但是因为它即将不可用,近期已完成迁移.建议大家使用 mavenCentral 的配置. 使用 jcenter implementation 'com.williamyang:gradienttext:1.0.1' 使用 mavenCentral buildscript { repositories {

  • Android Flutter实现GIF动画效果的方法详解

    目录 前言 交错动画机制 代码实现 Interval 介绍 总结 前言 我们之前介绍了不少有关动画的篇章.前面介绍的动画都是只有一个动画效果,那如果我们想对某个组件实现一组动效,比如下面的效果,该怎么办? staggered animation 这个时候我们需要用到组合动效, Flutter 提供了交错动画(Staggered Animation)的方式实现.对于多个 Anmation 对象,可以共用一个 AnimationController,然后在不同的时间段执行动画效果.这就有点像 GIF

  • Android动画之TranslateAnimation用法案例详解

    我们在实际的开发过程中,有很多地方需要使用TranslateAnimation,本文是爱站技术频道小编为大家做的简单介绍,下面是详解Android 动画之TranslateAnimation应用的参数说明,希望对你学习这方面知识有帮助! android中提供了4中动画: AlphaAnimation 透明度动画效果 ScaleAnimation 缩放动画效果 TranslateAnimation 位移动画效果 RotateAnimation 旋转动画效果 本节讲解TranslateAnimati

  • Jetpack Compose实现动画效果的方法详解

    目录 概述 低级别动画API animate*AsState 使用Animatable实现颜色变化效果 使用updateTransition实现颜色和圆角动画 rememberInfiniteTransition TargetBasedAnimation 自定义动画 AnimationSpec Easing AnimationVector 高级动画 概述 compose 为支持动画提供了大量的 api,通过这些 api 我们可以轻松实现动画效果 ps:这些 api 的原理与 Flutter 很接

  • Android 补间动画及组合AnimationSet常用方法详解

    目录 补间动画 RotateAnimation 动画示例 ScaleAnimation 动画示例 TranslateAnimation 动画示例 AlphaAnimation 动画示例 AnimationSet 动画组合 动画示例 补间动画 Android常用的四种补间动画分别为RotateAnimation.ScaleAnimation.TranslateAnimation.AlphaAnimation,他们的父类为Animation,UML类图如下: 父类通用方法有: public void

  • Android自定义指示器时间轴效果实例代码详解

    指示器时间轴在外卖.购物类的APP里会经常用到,效果大概就像下面这样,看了网上很多文章,大都是自己绘制,太麻烦,其实通过ListView就可以实现. 在Activity关联的布局文件activity_main.xml中放置一个ListView,代码如下.由于这个列表只是用于展示信息,并不需要用户去点击,所以将其clickable属性置为false:为了消除ListView点击产生的波纹效果,我们设置其listSelector属性的值为透明:我们不需要列表项之间的分割线,所以设置其divider属

随机推荐