Android開源中國客戶端學習 截屏模塊 <7>

此次分享的功能比較簡單,是osc的截屏模塊,效果以下 java

這個功能用戶體驗仍是不錯的,在不少軟件都也都內置了這個功能 canvas

這個功能的原理是: 函數

1.在須要截屏的activity的window上覆蓋一個ScreenShotView  this

2.用戶選定了截屏區域並雙擊後,ScreenShotView就會把當前activity的Decview畫到一個canvas上,並進行裁剪圖片和保存 url

具體實現過程: spa

時序圖以下: code

1.因爲這些操做都是在UIHelper中完成的,因此這裏從UIHelper開始,以前是在新聞詳情頁面點擊分享按鈕就調用UIHelper來生成contextmenu了 若是此時用戶選擇了截屏分享,那麼就會開始上圖的流程了首先是addScreenShot函數的執行 圖片


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函數以下:咱們來一步步分析:
/**
	 * 添加截屏功能
	 */
	@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添加了一個遮罩,也就是咱們點擊截屏後會顯示爲灰色而後讓用戶滑動選擇截屏區域 ip

@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了

/**
	 * 截取內層邊框中的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中進行分享和保存了

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就能夠了.

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息