編輯:關於Android編程
這麼長時間沒寫博客感覺手都要生了啊,最近因為工作的關系來到了上海,目前還算穩定,所以抓緊時間寫篇博客壓壓驚。

/**
* 獲得圖片
*/
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CHOOSE_BIG_PICTURE) {
photoBitmap = null;
photoViewBitmap = null;
try {
Uri originalUri = data.getData();
int angle = getExifOrientation(getRealPathFromURI(originalUri));
if (angle != 0) { // 如果照片出現了 旋轉 那麼 就更改旋轉度數
Matrix matrix = new Matrix();
matrix.postRotate(angle);
photoBitmap = getBitmapFromUri(photoBitmap, originalUri);
photoViewBitmap = Bitmap.createBitmap(photoBitmap, 0, 0,
photoBitmap.getWidth(), photoBitmap.getHeight(),
matrix, true);
clipView.setBitmap(photoViewBitmap);
} else {
clipView.setBitmap(getBitmapFromUri(photoBitmap,
originalUri));
}
photoBitmap.recycle();
photoViewBitmap.recycle();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
我當時用的是三星的Note3測試發現獲取的圖片會發生旋轉十分的坑爹。。所以我們還需要根據uri拿到路徑然後再判斷圖片是否旋轉。
/**
* 根據Uri獲得bitmap
*
* @param bitmap
* @param uri
* @return
*/
private Bitmap getBitmapFromUri(Bitmap bitmap, Uri uri) {
try {
bitmap = MediaStore.Images.Media.getBitmap(
this.getContentResolver(), uri);
return bitmap;
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
return null;
}
}
/**
* 獲得系統相冊圖片
*/
private void getAlbum() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(image/*);// 相片類型
startActivityForResult(intent, CHOOSE_BIG_PICTURE);
}
/**
* 旋轉圖片
*
* @param filepath
* @return
*/
private int getExifOrientation(String filepath) {
int degree = 0;
ExifInterface exif = null;
try {
exif = new ExifInterface(filepath);
} catch (IOException ex) {
}
if (exif != null) {
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, -1);
if (orientation != -1) {
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
}
}
return degree;
}
/**
* 根據Uri拿到路徑
*
* @param contentUri
* @return
*/
public String getRealPathFromURI(Uri contentUri) {
String res = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(contentUri, proj, null,
null, null);
if (cursor.moveToFirst()) {
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
public class ClipView extends View {
/**
* 畫筆
*/
private Paint paint;
/**
* 圖片
*/
private Bitmap mBitmap;
/**
* 畫布
*/
private Canvas mCanvas;
/**
* 蒙版
*/
private Bitmap bitmap;
/**
* 起點坐標
*/
private int startX, startY;
/**
* 移動距離
*/
private int distanceX, distanceY;
/**
* 圖片坐標
*/
private int widthX, heightY;
int x = 0, y = 0;
public ClipView(Context context) {
super(context);
init();
// TODO Auto-generated constructor stub
}
public ClipView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ClipView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
我們默認把傳進來的圖片縮放至600,800這樣不會讓圖片過大也不會過小。
/**
* 縮放圖片
*
* @param bgimage
* @param newWidth
* @param newHeight
* @return
*/
private Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight) {
// 獲取這個圖片的寬和高
float width = bgimage.getWidth();
float height = bgimage.getHeight();
// 創建操作圖片用的matrix對象
Matrix matrix = new Matrix();
// 計算寬高縮放率
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 縮放圖片動作
matrix.postScale(scaleWidth, scaleHeight);
Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
(int) height, matrix, true);
return bitmap;
}
/**
* 拿到圖片首先進行縮放
*
* @param bitmap
*/
public void setBitmap(Bitmap bitmap) {
this.mBitmap = zoomImage(bitmap, 600, 800);
startX = -(600 / 2);
startY = -(800 / 2);
widthX = startX;
heightY = startY;
postInvalidate();
}
做到這一步的時候我們再來看看效果 

private void init() {
// 創建空白畫布
bitmap = Bitmap.createBitmap(600, 800, Config.ARGB_8888);
mCanvas = new Canvas(bitmap);
paint = new Paint();
paint.setStyle(Style.FILL);
paint.setStrokeWidth(2);
paint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.translate(getWidth() / 2, getHeight() / 2);
if (mBitmap != null) {
restartCanvas();
canvas.drawBitmap(mBitmap, widthX, heightY, null);
mCanvas.drawCircle(-widthX, -heightY, 200, paint);
canvas.drawBitmap(bitmap, widthX, heightY, null);
}
}
我們再onDraw中繪制了我們的背景圖片以及蒙版效果再加一個半徑為200的圓,接下來做的就是不斷的改變背景位置來完成移動的效果,每次移動之前要先clear掉上次的畫布。
private void restartCanvas() {
// 清空上一次的繪圖狀態
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mCanvas.drawPaint(paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
mCanvas.drawColor(getResources().getColor(R.color.bg));
}
要記清楚DSTOUT的效果哦!
/**
* 移動x位置
*/
private void getWidthX() {
widthX = startX - distanceX;
if (widthX > -200) {
widthX = -200;
distanceX = -100;
} else if (widthX < -400) {
widthX = -400;
distanceX = 100;
}
}
/**
* 移動y位置
*/
private void getHeightY() {
heightY = startY - distanceY;
if (heightY > -200) {
heightY = -200;
distanceY = -100;
} else if (heightY < -600) {
heightY = -600;
distanceY = 100;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
y = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
distanceX = x - (int) (event.getX());
distanceY = y - (int) (event.getY());
getWidthX();
getHeightY();
break;
case MotionEvent.ACTION_UP:
startX = widthX;
startY = heightY;
break;
default:
break;
}
postInvalidate();
return true;
}
Android之斷點續傳下載
今天學習了Android開發中比較難的一個環節,就是斷點續傳下載,很多人看到這個標題就感覺頭大,的確,如果沒有良好的邏輯思維,這塊的確很難搞明白。下面我就將自己學到的知
Android - Android調用JNI方法 及 代碼
Android調用JNI方法 及 代碼 JNI: Java Native Interface, 實現Java和C/C++的互通. 在Andro
Android ViewPager畫廊效果詳解及實例
Android ViewPager 畫廊效果從上面的圖片可以看到,當添加多張圖片的時候,能夠在下方形成一個畫廊的效果,我們左右拉動圖片來看我們添加進去的圖片,效果是不是好
簡單談談android studio 的單元測試
面對android studio Run 一次項目要等好幾分鐘的痛點,不得不研究一下android studio 的單元測試。其實我的目的很簡單,在不對視圖進行操作的前提