Android 截图功能实现
•
移动开发
Android 截图功能实现
- 简介
- 效果图
- 功能实现
-
- 1. 截取当前可见范围屏幕
- 2. 截取当前可见范围屏幕(不包含状态栏)
- 3. 截取某个控件
- 4. 截取ScrollView
- 5. 长截图
- 6. 截屏动画效果
- 7. 显示截屏结果,自动消失
- 6. 完整代码
简介
在Android应用中开发截图功能涉及到以下几个步骤:获取屏幕内容、处理截图、保存截图等。
效果图


功能实现
1. 截取当前可见范围屏幕
/**
* 截取当前可见范围屏幕
*/
private void screenCapture() {
// View decorView = getWindow().getDecorView();
// decorView.setDrawingCacheEnabled(true);// 清空缓存,可用于实时截图
// decorView.buildDrawingCache();
// Bitmap screenBitmap = Bitmap.createBitmap(decorView.getDrawingCache());
// decorView.setDrawingCacheEnabled(false); // 清空缓存,可用于实时截图
View decorView = getWindow().getDecorView();
Bitmap screenBitmap = Bitmap.createBitmap(decorView.getWidth(), decorView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(screenBitmap);
decorView.draw(canvas);
updateImageCapture(screenBitmap);
}
2. 截取当前可见范围屏幕(不包含状态栏)
/**
* 截取当前可见范围屏幕(不包含状态栏)
*/
private void screenCaptureNoStatusBar() {
View view = getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
// 获取状态栏高度
Rect rect = new Rect();
view.getWindowVisibleDisplayFrame(rect);
int statusBarH = rect.top;
// 获取屏幕宽高
int w = view.getWidth();
int h = view.getHeight();
// 去掉状态栏
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, statusBarH, w, h - statusBarH);
// 销毁缓存信息
view.destroyDrawingCache();
updateImageCapture(bitmap);
}
3. 截取某个控件
/**
* 截取某个控件
* @param view
*/
private void screenCapture(View view) {
Bitmap screenBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(screenBitmap);
view.draw(canvas);
updateImageCapture(screenBitmap);
}
4. 截取ScrollView
/**
* 截取ScrollView
* @param view
*/
private void screenCapture(ScrollView view) {
int h = 0;
for (int i = 0; i < view.getChildCount(); i++) {
h += view.getChildAt(i).getHeight();
view.getChildAt(i).setBackgroundColor(Color.parseColor("#FFFFFF"));
}
Bitmap screenBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(screenBitmap);
view.draw(canvas);
updateImageCapture(screenBitmap);
}
5. 长截图
/**
* 滚屏截长图
*/
private Runnable scrollRunnable = new Runnable() {
@SuppressLint("NewApi")
@Override
public void run() {
boolean isToBottom = isScrollToEnd();
if (isToBottom) {
Log.i(TAG, "run: to bottom");
Thread.currentThread().interrupt();
mHandler.removeCallbacks(scrollRunnable);
screenCapture(scrollView);
} else {
// 未滑动到底部
int off = linearLayout.getMeasuredHeight() - scrollView.getHeight(); // 判断高度
if (off > 0) {
scrollView.scrollBy(0, 6);
if (scrollView.getScaleY() >= off) {
Thread.currentThread().interrupt();
mHandler.removeCallbacks(scrollRunnable);
} else {
mHandler.postDelayed(this, 10);
}
}
}
}
};
6. 截屏动画效果
截屏时有一个缩放的动画效果,缩放到右上角。
- 动画效果文件,/res/anim/scale_animation.xml文件。
- 代码中使用动画效果
mCardView.startAnimation(animation);
7. 显示截屏结果,自动消失
截屏完成,会将截取的图片显示在界面中,显示截屏3s后会自动消失。
/**
* 显示截图3s后自动消失
*/
private Runnable captureViewRunnable = new Runnable() {
@SuppressLint("NewApi")
@Override
public void run() {
mCardView.clearAnimation();
mCardView.setVisibility(View.INVISIBLE);
}
};
6. 完整代码
- 布局文件:activity_screenshot.xml。
- Activity文件:ScreenshotActivity.java。
public class ScreenshotActivity extends AppCompatActivity {
private static final String TAG = "ScreenshotActivity";
private ScrollView scrollView;
private LinearLayout linearLayout;
private ImageView ivScreenshots;
private CardView mCardView;
private Handler mHandler = new Handler();
// 截图动画
private Animation animation;
// 截图显示的时间,超时后消失
private static final int CAPTURE_SHOW_TIMEOUT = 3000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screenshot);
scrollView = findViewById(R.id.scroll_view);
linearLayout = findViewById(R.id.linear_layout);
ivScreenshots = findViewById(R.id.iv_capture);
mCardView = findViewById(R.id.cardView);
Button btnScreenshots = findViewById(R.id.btn_screenshot);
Button btnLong = findViewById(R.id.bnt_long);
animation = AnimationUtils.loadAnimation(this, R.anim.scale_animation);
animation.setFillAfter(true);
// 动态添加textview
for (int i = 0; i < 50; i++) {
TextView textView = new TextView(this);
textView.setText("item-" + (i + 1));
textView.setGravity(Gravity.CENTER);
textView.setTextSize(16);
linearLayout.addView(textView);
}
btnScreenshots.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// screenCapture();
// screenCapture(scrollView);
screenCapture(scrollView);
// screenCaptureNoStatusBar();
}
});
btnLong.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHandler.post(scrollRunnable);
}
});
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mHandler.postDelayed(captureViewRunnable, CAPTURE_SHOW_TIMEOUT);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
@Override
protected void onPause() {
super.onPause();
mHandler.removeCallbacks(scrollRunnable);
mHandler.removeCallbacks(captureViewRunnable);
}
/**
* 滚屏的线程
*/
private Runnable scrollRunnable = new Runnable() {
@SuppressLint("NewApi")
@Override
public void run() {
boolean isToBottom = isScrollToEnd();
if (isToBottom) {
Log.i(TAG, "run: to bottom");
Thread.currentThread().interrupt();
mHandler.removeCallbacks(scrollRunnable);
screenCapture(scrollView);
} else {
// 未滑动到底部
int off = linearLayout.getMeasuredHeight() - scrollView.getHeight(); // 判断高度
if (off > 0) {
scrollView.scrollBy(0, 6);
if (scrollView.getScaleY() >= off) {
Thread.currentThread().interrupt();
mHandler.removeCallbacks(scrollRunnable);
} else {
mHandler.postDelayed(this, 10);
}
}
}
}
};
/**
* 显示截图3s后自动消失
*/
private Runnable captureViewRunnable = new Runnable() {
@SuppressLint("NewApi")
@Override
public void run() {
mCardView.clearAnimation();
mCardView.setVisibility(View.INVISIBLE);
}
};
/**
* 截取当前可见范围屏幕
*/
private void screenCapture() {
// View decorView = getWindow().getDecorView();
// decorView.setDrawingCacheEnabled(true);// 清空缓存,可用于实时截图
// decorView.buildDrawingCache();
// Bitmap screenBitmap = Bitmap.createBitmap(decorView.getDrawingCache());
// decorView.setDrawingCacheEnabled(false); // 清空缓存,可用于实时截图
View decorView = getWindow().getDecorView();
Bitmap screenBitmap = Bitmap.createBitmap(decorView.getWidth(), decorView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(screenBitmap);
decorView.draw(canvas);
updateImageCapture(screenBitmap);
}
/**
* 截取某个控件
* @param view
*/
private void screenCapture(View view) {
Bitmap screenBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(screenBitmap);
view.draw(canvas);
updateImageCapture(screenBitmap);
}
/**
* 截取ScrollView
* @param view
*/
private void screenCapture(ScrollView view) {
int h = 0;
for (int i = 0; i < view.getChildCount(); i++) {
h += view.getChildAt(i).getHeight();
view.getChildAt(i).setBackgroundColor(Color.parseColor("#FFFFFF"));
}
Bitmap screenBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(screenBitmap);
view.draw(canvas);
updateImageCapture(screenBitmap);
}
/**
* 截取当前可见范围屏幕(不包含状态栏)
*/
private void screenCaptureNoStatusBar() {
View view = getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
// 获取状态栏高度
Rect rect = new Rect();
view.getWindowVisibleDisplayFrame(rect);
int statusBarH = rect.top;
// 获取屏幕宽高
int w = view.getWidth();
int h = view.getHeight();
// 去掉状态栏
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, statusBarH, w, h - statusBarH);
// 销毁缓存信息
view.destroyDrawingCache();
updateImageCapture(bitmap);
}
private void updateImageCapture(final Bitmap screenBitmap) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mCardView.setVisibility(View.VISIBLE);
ivScreenshots.setImageBitmap(screenBitmap);
}
});
mCardView.startAnimation(animation);
}
/**
* scrollview是否已经滑到底部
* @return
*/
private boolean isScrollToEnd() {
// 获取 ScrollView 的可视高度
int visibleHeight = scrollView.getHeight() - scrollView.getPaddingTop() - scrollView.getPaddingBottom();
// 获取 ScrollView 的子View
View lastChild = scrollView.getChildAt(scrollView.getChildCount() - 1);
// 获取 ScrollView 可以滑动的范围
int scrollRange = scrollView.getChildAt(0).getHeight() - scrollView.getHeight();
// 获取 ScrollView 的滚动位置
int scrollY = scrollView.getScrollY();
// 计算ScrollView底部位置
int scrollViewBottom = scrollY + visibleHeight;
// 获取ScrollView的子View的底部位置
int lastChildBottom = lastChild.getBottom();
// 判断 ScrollView 是否滚动到底部
if (scrollY == scrollRange) {
// 已滑动到底部
return true;
} else if (scrollViewBottom >= lastChildBottom) {
// scrollTo 和 scrollTo 不是同时回调,所以添加两个逻辑都可(可根据需要决定是否需要使用两个逻辑组合)
// 已滑动到底部
return true;
} else {
return false;
}
}
}
- 截图动画文件:scale_animation.xml。
本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://www.net2asp.com/ca0a8f163d.html
