Android开源中国客户端学习 截屏模块 <7>




![图片说明文字][1]


这个功能用户体验还是不错的,在很多软件都也都内置了这个功能


这个功能的原理是:


1.在需要截屏的activity的window上覆盖一个ScreenShotView 


2.用户选定了截屏区域并双击后,ScreenShotView就会把当前activity的Decview画到一个canvas上,并进行裁剪图片和保存


具体实现过程:


时序图如下:
![图片说明文字][2]




1.由于这些操作都是在UIHelper中完成的,所以这里从UIHelper开始,之前是在新闻详情页面点击分享按钮就调用UIHelper来生成contextmenu了 如果此时用户选择了截屏分享,那么就会开始上图的流程了首先是addScreenShot函数的执行


```java
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函数如下:我们来一步步分析:


```java
/**
* 添加截屏功能
*/
@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添加了一个遮罩,也就是我们点击截屏后会显示为灰色然后让用户滑动选择截屏区域


```java
@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只会 会调用


```java
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了


```java
/**
* 截取内层边框中的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中进行分享和保存了


```java
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就可以了.**


  [1]: http://a1.eoe.cn/www/home/201307/07/5214/51d9554d19d11.png "QQ截图20130707172557.png"
  [2]: http://a1.eoe.cn/www/home/201307/07/9e73/51d955403db50.png "QQ截图20130707175958.png"

转载于:https://my.oschina.net/Ci3giemTe/blog/145173

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值