Activity界面區(qū)域劃分
如圖:最大的紅色區(qū)域是屏幕界面,綠色次大區(qū)域我們稱之為“應(yīng)用界面區(qū)域”,藍色的區(qū)域我們稱之為“View繪制區(qū)域”;屏幕頂端、應(yīng)用界面區(qū)之外的那部分顯示手機電池網(wǎng)絡(luò)運營商信息的為“狀態(tài)欄”,應(yīng)用區(qū)域頂端、View繪制區(qū)外部顯示Activity名稱的部分我們稱為“標(biāo)題欄”。
獲取狀態(tài)欄高度
獲取狀態(tài)欄一般常用的有三種方法:
-
通過系統(tǒng)資源尺寸獲取
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); if(resourceId > 0){ int statusBarHeight = getResources().getDimensionPixelSize(resourceId); }
使用getIdentifier()方法
方法一
Resources resources = context.getResources();
int resourceId = resources.getIdentifier(com.test.androidtest:drawable/icon",null,null);
第一個參數(shù)格式是:包名 + : + 資源文件夾名 + / +資源名,然后其他的可以為null #####方法二Resources resources = context.getResources();
int resourceId = getResources().getIdentifier("icon", "drawable", "com.test.androidtest");第一個參數(shù)為ID名,第二個為資源屬性是ID或者是Drawable,第三個為包名。 一般來講是推薦第二種方法
在獲取狀態(tài)欄高度時, 因為狀態(tài)欄高度定義在Android系統(tǒng)尺寸資源中status_bar_height,但并不能公開使用,一般會像這樣使用:android.R.dimen.status_bar_height,由于系統(tǒng)為我們提供了一個Resource類,所以我們可以通過這個類來獲取資源 status_bar_height.
因此代碼的寫法是
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
可對照getIdentifier()的方法二進行比對
-
使用屏幕和應(yīng)用區(qū)域高度的差值確定
// 獲取狀態(tài)欄高度 Rect frame = new Rect(); // 測量屏幕寬和高 view.getWindowVisibleDisplayFrame(frame); int stautsHeight = frame.top;如果單單獲取statusBar高度而不獲取titleBar高度時,這種方法并不推薦大家使用,因為這種方法依賴于WMS(窗口管理服務(wù)的回調(diào))。正是因為窗口回調(diào)機制,所以在Activity初始化時執(zhí)行此方法得到的高度是0,這就是很多人獲取到statusBar高度為0的原因。這個方法推薦在回調(diào)方法onWindowFocusChanged()中執(zhí)行,才能得到預(yù)期結(jié)果。
-
使用應(yīng)用區(qū)域的top屬性
//屏幕 DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); //應(yīng)用區(qū)域 Rect outRect1 = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect1); int statusBar = dm.heightPixels - outRect1.height(); //狀態(tài)欄高度=屏幕高度-應(yīng)用區(qū)域高度
獲取標(biāo)題欄高度
- 通過View提供的方法獲取高度
int viewTop = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
通過Activity的getWindow().findViewById(Window.ID_ANDROID_CONTENT)獲取系統(tǒng)當(dāng)前顯示的view根(是一個framelayout對象),android繪制會將要繪制的view放置在framelayout中繪制。
- 通過屏幕獲取高度
int statusHeight = -1;
//屏幕
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusHeight = activity.getResources().getDimensionPixelSize(resourceId);
}
//View繪制區(qū)域,//viewtop方法一
Rect outRect2 = new Rect();
activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getDrawingRect(outRect2);
int viewTop = dm.heightPixels - statusHeight - outRect2.height();
寫入SD卡
private static boolean savePic(Bitmap pBitmap, File strName) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(strName);
if (null != fos) {
pBitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.flush();
fos.close();
return true;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
關(guān)于flush()方法,api中有如下描述
刷新此輸出流并強制寫出所有緩沖的輸出字節(jié)(刷新數(shù)據(jù)并將數(shù)據(jù)轉(zhuǎn)交給操作系統(tǒng) )
實現(xiàn)截圖
/**
* 截圖
*
* @param activity
* @return 截圖并且保存sdcard成功返回true,否則返回false
*/
public static boolean shotBitmap(Activity activity) {
String sdCardDir = Environment.getExternalStorageDirectory() + "/jietu/";
File dirFile = new File(sdCardDir); //目錄轉(zhuǎn)化成文件夾
if (!dirFile.exists()) { //如果不存在,那就建立這個文件夾
dirFile.mkdirs();
}
//指定目錄
File file = new File(sdCardDir, System.currentTimeMillis() + ".png");
return ScreenShotUtils.savePic(takeScreenShot(activity), file);
}
Environment.getExternalStorageDirectory()是獲得根目錄,System.currentTimeMillis()是獲得系統(tǒng)時間
File file = new File(sdCardDir, System.currentTimeMillis() + ".png");
這句話的意思就是,截下來的圖以 ==當(dāng)前系統(tǒng)時間戳.png== 的形式存到根目錄下的 ==jietu== 文件夾下。
終極代碼
MainActivity:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean result = ScreenShotUtils.shotBitmap(MainActivity.this);
if (result) {
Toast.makeText(MainActivity.this, "截圖成功.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "截圖失敗.", Toast.LENGTH_SHORT).show();
}
}
});
}
}
ScreenShotUtils:
/**
* 進行截屏工具類
*/
public class ScreenShotUtils {
/**
* 進行截取屏幕
*
* @param activity
* @return bitmap
*/
public static Bitmap takeScreenShot(Activity activity) {
Bitmap bitmap = null;
int statusHeight = -1;
View view = activity.getWindow().getDecorView();
// 設(shè)置是否可以進行繪圖緩存
view.setDrawingCacheEnabled(true);
// 如果繪圖緩存無法,強制構(gòu)建繪圖緩存
view.buildDrawingCache();
// 返回這個緩存視圖
bitmap = view.getDrawingCache();
Log.d("123", "bitmap.getHeight():" + bitmap.getHeight());
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusHeight = activity.getResources().getDimensionPixelSize(resourceId);
}
int viewTop = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay().getHeight();
// 根據(jù)坐標(biāo)點和需要的寬和高創(chuàng)建bitmap
bitmap = Bitmap.createBitmap(bitmap, 0, statusHeight + viewTop, width, height - statusHeight - viewTop);
return bitmap;
}
/**
* 保存圖片到sdcard中
*
* @param pBitmap
*/
private static boolean savePic(Bitmap pBitmap, File strName) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(strName);
if (null != fos) {
pBitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.flush();
fos.close();
return true;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* 截圖
*
* @param activity
* @return 截圖并且保存sdcard成功返回true,否則返回false
*/
public static boolean shotBitmap(Activity activity) {
String sdCardDir = Environment.getExternalStorageDirectory() + "/wurenji/";
File dirFile = new File(sdCardDir); //目錄轉(zhuǎn)化成文件夾
if (!dirFile.exists()) { //如果不存在,那就建立這個文件夾
dirFile.mkdirs();
}
//指定目錄
File file = new File(sdCardDir, System.currentTimeMillis() + ".png");
return ScreenShotUtils.savePic(takeScreenShot(activity), file);
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/gray"
tools:context="com.test.screenshot.MainActivity">
<TextView
android:id="@+id/tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="點擊截圖哦"
android:gravity="center"
android:padding="10dp"
android:textSize="20sp" />
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dip"
android:scaleType="fitXY" />
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dip"
android:text="點擊截圖" />
</LinearLayout>