編輯:關於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調用JNI方法 及 代碼 JNI: Java Native Interface, 實現Java和C/C++的互通. 在Andro
Android ViewPager 畫廊效果從上面的圖片可以看到,當添加多張圖片的時候,能夠在下方形成一個畫廊的效果,我們左右拉動圖片來看我們添加進去的圖片,效果是不是好
面對android studio Run 一次項目要等好幾分鐘的痛點,不得不研究一下android studio 的單元測試。其實我的目的很簡單,在不對視圖進行操作的前提