这次分享的功能比较简单,是osc的截屏模块,效果如下
这个功能用户体验还是不错的,在很多软件都也都内置了这个功能
这个功能的原理是:
1.在需要截屏的activity的window上覆盖一个ScreenShotView
2.用户选定了截屏区域并双击后,ScreenShotView就会把当前activity的Decview画到一个canvas上,并进行裁剪图片和保存
具体实现过程:
时序图如下:
1.由于这些操作都是在UIHelper中完成的,所以这里从UIHelper开始,之前是在新闻详情页面点击分享按钮就调用UIHelper来生成contextmenu了 如果此时用户选择了截屏分享,那么就会开始上图的流程了首先是addScreenShot函数的执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
addScreenShot(context, new OnScreenShotListener() {
@SuppressLint("NewApi")
public void onComplete(Bitmap bm) {
Intent intent = new Intent(context,ScreenShotShare.class);
intent.putExtra("title", title);
intent.putExtra("url", url);
intent.putExtra("cut_image_tmp_path",ScreenShotView.TEMP_SHARE_FILE_NAME);
try {
ImageUtils.saveImageToSD(context,ScreenShotView.TEMP_SHARE_FILE_NAME,bm, 100);
} catch (IOException e) {
e.printStackTrace();
}
context.startActivity(intent);
}
});
|
很简单,就是传入了context 并实现了一个listener,这个listener用来处理ScreenShotview的回调,addScreenShot函数如下:我们来一步步分析:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/**
* 添加截屏功能
*/
@SuppressLint("NewApi")
public static void addScreenShot(Activity context,
OnScreenShotListener mScreenShotListener) {
BaseActivity cxt = null;
if (context instanceof BaseActivity) {
cxt = (BaseActivity) context;
cxt.setAllowFullScreen(false);
ScreenShotView screenShot = new ScreenShotView(cxt,
mScreenShotListener);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
context.getWindow().addContentView(screenShot, lp);
}
}
|
2.初始化ScreenShotView 这个构造函数主要是给当前的ScreenShotView添加了一个遮罩,也就是我们点击截屏后会显示为灰色然后让用户滑动选择截屏区域
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
@SuppressLint("NewApi")
public ScreenShotView(BaseActivity context, OnScreenShotListener listener) {
super(context);
mListener = listener;
mContext = context;
mContext.setAllowDestroy(false, this);
Point p = getDisplaySize(context.getWindowManager().getDefaultDisplay());
screenWidth = p.x;
screeenHeight = p.y;
mGrayPaint = new Paint();
mGrayPaint.setARGB(100, 0, 0, 0);
topRect = new Rect();
rightRect = new Rect();
bottomRect = new Rect();
leftRect = new Rect();
topRect.set(0, 0, screenWidth, screeenHeight);
setOnTouchListener(this);
if(bmDoubleClickTip==null){
bmDoubleClickTip = BitmapFactory.decodeStream(getResources().openRawResource(R.drawable._pointer));
}
UIHelper.ToastMessage(mContext, "请滑动手指确定选区!");
}
|
ScreenShotView的其他处理也是围绕怎么跟随用户画出选区展开的,这里就不一一描述了
3.初始化完毕了ScreenShotView只会 会调用
|
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
context.getWindow().addContentView(screenShot, lp);
|
这样就把ScreenShotView添加到了当前的activity的window中去了.
4.如果用户操作完之后,双击了屏幕,经过一系列的判断,就会执行回调了,代码如下:
mListener.onComplete(getCutImage());
5-8 我们看一下getCutImage函数,原来是先获取当前decorview的bitmap,然后按照用户操作界面计算出来的模板进行裁剪 就得到截图区域的bitmap了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/**
* 截取内层边框中的View.
*/
private Bitmap getCutImage() {
View view = mContext.getWindow().getDecorView();
Bitmap bmp = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
view.draw(canvas);
return imageCrop(bmp);
}
/**
* 裁剪图片
*/
private Bitmap imageCrop(Bitmap bitmap) {
int x = left<0?0:left;
int y = top + getStatusHeight();
int width = right- left;
int height = bottom - top;
if((width+x)>bitmap.getWidth()){
width = bitmap.getWidth()-x;
}
if((y+height)>bitmap.getHeight()){
height = bitmap.getHeight()-y;
}
return Bitmap.createBitmap(bitmap,x,y,width,height , null, false);
}
|
9.拿到这个bitmap ,就可以在UIHelper中进行分享和保存了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
addScreenShot(context, new OnScreenShotListener() {
@SuppressLint("NewApi")
public void onComplete(Bitmap bm) {
Intent intent = new Intent(context,ScreenShotShare.class);
intent.putExtra("title", title);
intent.putExtra("url", url);
intent.putExtra("cut_image_tmp_path",ScreenShotView.TEMP_SHARE_FILE_NAME);
try {
ImageUtils.saveImageToSD(context,ScreenShotView.TEMP_SHARE_FILE_NAME,bm, 100);
} catch (IOException e) {
e.printStackTrace();
}
context.startActivity(intent);
}
});
|
当然,其实在实际开发中,我们只需要调用这个ScreenShotView就可以了.
所有评论(0)