您好,登錄后才能下訂單哦!
小編給大家分享一下Android如何實(shí)現(xiàn)網(wǎng)絡(luò)加載圖片點(diǎn)擊大圖后瀏覽可縮放,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
具體內(nèi)容如下
找了一些demo感覺沒有自己想要的效果,于是借鑒一些改造一下并記錄下來;
1、主Activity
public class PictureViewFra extends Activity { private PicGallery gallery; // private ViewGroup tweetLayout; // 彈層 private boolean mTweetShow = false; // 彈層是否顯示 // 屏幕寬度 public static int screenWidth; // 屏幕高度 public static int screenHeight; private GalleryAdapter mAdapter; private ArrayList<HelpTopicImageBean> helpTopicImage = new ArrayList<HelpTopicImageBean>(); private int position = 0; // private ProgressDialog mProgress; private TextView tv_img_count,tv_topic_title; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.picture_view); getIntentData(); tv_img_count = (TextView)findViewById(R.id.tv_img_count); tv_topic_title = (TextView)findViewById(R.id.tv_topic_title); gallery = (PicGallery) findViewById(R.id.pic_gallery); gallery.setVerticalFadingEdgeEnabled(false);// 取消豎直漸變邊框 gallery.setHorizontalFadingEdgeEnabled(false);// 取消水平漸變邊框 gallery.setDetector(new GestureDetector(this, new MySimpleGesture())); mAdapter = new GalleryAdapter(this,helpTopicImage,position); gallery.setAdapter(mAdapter); gallery.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { return false; } }); mAdapter.getPositionListener(new GalleryAdapter.GalleryPositionListener() { @Override public void movePosition(int index) { Log.d("helpTopicImage--> ", " " + index); tv_img_count.setText((index+1)+"/"+helpTopicImage.size()); tv_topic_title.setText(helpTopicImage.get(index).getImgInfo()); } }); // mAdapter.setData(dataResult); initViews(); // mProgress = ProgressDialog.show(getActivity(), // null,getActivity().getString(R.string.loading)); } private void getIntentData() { Intent intent = getIntent(); helpTopicImage = (ArrayList<HelpTopicImageBean>)intent.getSerializableExtra("helpTopicImage"); position = intent.getIntExtra("position", 0); } private void initViews() { screenWidth = getWindow().getWindowManager().getDefaultDisplay() .getWidth(); screenHeight = getWindow().getWindowManager().getDefaultDisplay() .getHeight(); } private class MySimpleGesture extends SimpleOnGestureListener { // 按兩下的第二下Touch down時(shí)觸發(fā) public boolean onDoubleTap(MotionEvent e) { View view = gallery.getSelectedView(); if (view instanceof MyImageView) { MyImageView imageView = (MyImageView) view; if (imageView.getScale() > imageView.getMiniZoom()) { imageView.zoomTo(imageView.getMiniZoom()); } else { imageView.zoomTo(imageView.getMaxZoom()); } } else { } return true; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { // Logger.LOG("onSingleTapConfirmed", // "onSingleTapConfirmed excute"); // mTweetShow = !mTweetShow; // tweetLayout.setVisibility(mTweetShow ? View.VISIBLE // : View.INVISIBLE); return true; } } }
2、顯示圖片的GalleryAdapter
public class GalleryAdapter extends BaseAdapter { private Context context; private ArrayList<MyImageView> imageViews = new ArrayList<MyImageView>(); private GalleryPositionListener positionListener; private ArrayList<HelpTopicImageBean> helpTopicImage = new ArrayList<HelpTopicImageBean>(); private int position = 0; private ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(); private Handler handler = new Handler() { public void handleMessage(Message msg) { Bitmap bitmap = (Bitmap) msg.obj; Bundle bundle = msg.getData(); String url = bundle.getString("url"); for (int i = 0; i < imageViews.size(); i++) { if (imageViews.get(i).getTag().equals(url)) { imageViews.get(i).setImageBitmap(bitmap); } } } }; public void setData(List<Integer> data) { notifyDataSetChanged(); } public GalleryAdapter(Context context,ArrayList<HelpTopicImageBean> helpTopicImage,int position) { this.context = context; this.helpTopicImage = helpTopicImage; this.position = position; for(int i=0; i<helpTopicImage.size(); i++){ Bitmap bitmap = ImageLoader.getInstance().loadImageSync(helpTopicImage.get(i).getImgUrl()); bitmaps.add(bitmap); } } @Override public int getCount() { return helpTopicImage.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { MyImageView view = new MyImageView(context); view.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); if (bitmaps.get(position) != null) { view.setImageBitmap(bitmaps.get(position)); } if (!this.imageViews.contains(view)) { imageViews.add(view); } positionListener.movePosition(position); return view; } public void getPositionListener(GalleryPositionListener positionListener) { this.positionListener = positionListener; } public interface GalleryPositionListener{ public void movePosition(int index); } }
3、自定義的 Gallery
public class PicGallery extends Gallery { private GestureDetector gestureScanner; private MyImageView imageView; public PicGallery(Context context) { super(context); } public PicGallery(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setDetector(GestureDetector dectector) { gestureScanner = dectector; } public PicGallery(Context context, AttributeSet attrs) { super(context, attrs); this.setOnTouchListener(new OnTouchListener() { float baseValue; float originalScale; @Override public boolean onTouch(View v, MotionEvent event) { View view = PicGallery.this.getSelectedView(); if (view instanceof MyImageView) { imageView = (MyImageView) view; if (event.getAction() == MotionEvent.ACTION_DOWN) { baseValue = 0; originalScale = imageView.getScale(); } if (event.getAction() == MotionEvent.ACTION_MOVE) { if (event.getPointerCount() == 2) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); float value = (float) Math.sqrt(x * x + y * y);// 計(jì)算兩點(diǎn)的距離 // System.out.println("value:" + value); if (baseValue == 0) { baseValue = value; } else { float scale = value / baseValue;// 當(dāng)前兩點(diǎn)間的距離除以手指落下時(shí)兩點(diǎn)間的距離就是需要縮放的比例。 // scale the image imageView.zoomTo(originalScale * scale, x + event.getX(1), y + event.getY(1)); } } } } return false; } }); } float v[] = new float[9]; @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { View view = PicGallery.this.getSelectedView(); if (view instanceof MyImageView) { float xdistance = calXdistance(e1, e2); float min_distance = PictureViewFra.screenWidth / 4f; if (isScrollingLeft(e1, e2) && xdistance > min_distance) { kEvent = KeyEvent.KEYCODE_DPAD_LEFT; } else if (!isScrollingLeft(e1, e2) && xdistance > min_distance) { kEvent = KeyEvent.KEYCODE_DPAD_RIGHT; } imageView = (MyImageView) view; Matrix m = imageView.getImageMatrix(); m.getValues(v); // 圖片實(shí)時(shí)的上下左右坐標(biāo) float left, right; // 圖片的實(shí)時(shí)寬,高 float width = imageView.getScale() * imageView.getImageWidth(); float height = imageView.getScale() * imageView.getImageHeight(); if ((int) width <= PictureViewFra.screenWidth && (int) height <= PictureViewFra.screenHeight)// 如果圖片當(dāng)前大小<屏幕大小,直接處理滑屏事件 { super.onScroll(e1, e2, distanceX, distanceY); } else { left = v[Matrix.MTRANS_X]; right = left + width; Rect r = new Rect(); imageView.getGlobalVisibleRect(r); if (distanceX > 0)// 向左滑動(dòng) { if (r.left > 0 || right < PictureViewFra.screenWidth) {// 判斷當(dāng)前ImageView是否顯示完全 super.onScroll(e1, e2, distanceX, distanceY); } else { imageView.postTranslate(-distanceX, -distanceY); } } else if (distanceX < 0)// 向右滑動(dòng) { if (r.right < PictureViewFra.screenWidth || left > 0) { super.onScroll(e1, e2, distanceX, distanceY); } else { imageView.postTranslate(-distanceX, -distanceY); } } } } else { super.onScroll(e1, e2, distanceX, distanceY); } return false; } private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2) { return e2.getX() > e1.getX(); } private float calXdistance(MotionEvent e1, MotionEvent e2) { return Math.abs(e2.getX() - e1.getX()); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } @Override public boolean onTouchEvent(MotionEvent event) { //Logger.d(DEBUG,"[PicGallery.onTouchEvent]"+"PicGallery.onTouchEvent"); if (gestureScanner != null) { gestureScanner.onTouchEvent(event); } switch (event.getAction()) { case MotionEvent.ACTION_UP: // 判斷邊界是否越界 View view = PicGallery.this.getSelectedView(); if (view instanceof MyImageView) { if(kEvent != KEY_INVALID) { // 是否切換上一頁(yè)或下一頁(yè) onKeyDown(kEvent, null); kEvent = KEY_INVALID; } imageView = (MyImageView) view; float width = imageView.getScale() * imageView.getImageWidth(); float height = imageView.getScale() * imageView.getImageHeight(); // Logger.LOG("onTouchEvent", "width=" + width + ",height=" // + height + ",screenWidth=" // + PictureViewActivity.screenWidth + ",screenHeight=" // + PictureViewActivity.screenHeight); if ((int) width <= PictureViewFra.screenWidth && (int) height <= PictureViewFra.screenHeight)// 如果圖片當(dāng)前大小<屏幕大小,判斷邊界 { break; } float v[] = new float[9]; Matrix m = imageView.getImageMatrix(); m.getValues(v); float top = v[Matrix.MTRANS_Y]; float bottom = top + height; if (top < 0 && bottom < PictureViewFra.screenHeight) { // imageView.postTranslateDur(-top, 200f); imageView.postTranslateDur(PictureViewFra.screenHeight - bottom, 200f); } if (top > 0 && bottom > PictureViewFra.screenHeight) { // imageView.postTranslateDur(PictureViewActivity.screenHeight // - bottom, 200f); imageView.postTranslateDur(-top, 200f); } float left =v[Matrix.MTRANS_X]; float right = left + width; if(left<0 && right< PictureViewFra.screenWidth){ // imageView.postTranslateXDur(-left, 200f); imageView.postTranslateXDur(PictureViewFra.screenWidth - right, 200f); } if(left>0 && right>PictureViewFra.screenWidth){ // imageView.postTranslateXDur(PictureViewActivity.screenWidth // - right, 200f); imageView.postTranslateXDur(-left, 200f); } } break; } return super.onTouchEvent(event); } int kEvent = KEY_INVALID; //invalid public static final int KEY_INVALID = -1; }
4、自定義的ImageView
public class MyImageView extends ImageView { // This is the base transformation which is used to show the image // initially. The current computation for this shows the image in // it's entirety, letterboxing as needed. One could choose to // show the image as cropped instead. // // This matrix is recomputed when we go from the thumbnail image to // the full size image. protected Matrix mBaseMatrix = new Matrix(); // This is the supplementary transformation which reflects what // the user has done in terms of zooming and panning. // // This matrix remains the same when we go from the thumbnail image // to the full size image. protected Matrix mSuppMatrix = new Matrix(); // This is the final matrix which is computed as the concatentation // of the base matrix and the supplementary matrix. private final Matrix mDisplayMatrix = new Matrix(); // Temporary buffer used for getting the values out of a matrix. private final float[] mMatrixValues = new float[9]; // The current bitmap being displayed. protected Bitmap image = null; protected Handler mHandler = new Handler(); int mThisWidth = -1, mThisHeight = -1;//布局后的寬度和高度,由于是全屏顯示,這兩個(gè)值等于屏幕分辨率 float mMaxZoom;// 最大縮放比例 float mMinZoom;// 最小縮放比例 private int imageWidth;// 圖片的原始寬度 private int imageHeight;// 圖片的原始高度 // float scaleRate;// 圖片適應(yīng)屏幕的縮放比例 static final float SCALE_RATE = 1.25F; public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyImageView(Context context) { super(context); init(); } @Override public void setImageBitmap(Bitmap bitmap) { super.setImageBitmap(bitmap); image = bitmap; setImageHeight(bitmap.getHeight()); setImageWidth(bitmap.getWidth()); Drawable d = getDrawable(); if (d != null) { d.setDither(true); } } // Center as much as possible in one or both axis. Centering is // defined as follows: if the image is scaled down below the // view's dimensions then center it (literally). If the image // is scaled larger than the view and is translated out of view // then translate it back into view (i.e. eliminate black bars). protected void center(boolean horizontal, boolean vertical) { if (image == null) { return; } Matrix m = getImageViewMatrix(); RectF rect = new RectF(0, 0, image.getWidth(), image.getHeight()); // RectF rect = new RectF(0, 0, imageWidth*getScale(), // imageHeight*getScale()); m.mapRect(rect); float height = rect.height(); float width = rect.width(); float deltaX = 0, deltaY = 0; if (vertical) { int viewHeight = getHeight(); if (height < viewHeight) { deltaY = (viewHeight - height) / 2 - rect.top; } else if (rect.top > 0) { deltaY = -rect.top; } else if (rect.bottom < viewHeight) { deltaY = getHeight() - rect.bottom; } } if (horizontal) { int viewWidth = getWidth(); if (width < viewWidth) { deltaX = (viewWidth - width) / 2 - rect.left; } else if (rect.left > 0) { deltaX = -rect.left; } else if (rect.right < viewWidth) { deltaX = viewWidth - rect.right; } } postTranslate(deltaX, deltaY); setImageMatrix(getImageViewMatrix()); } private void init() { setScaleType(ScaleType.MATRIX); } // Setup the base matrix so that the image is centered and scaled properly. private void getProperBaseMatrix(Bitmap bitmap, Matrix matrix) { float viewWidth = getWidth(); float viewHeight = getHeight(); float w = bitmap.getWidth(); float h = bitmap.getHeight(); matrix.reset(); // We limit up-scaling to 3x otherwise the result may look bad if it's // a small icon. float scale = Math.min(viewWidth / w, viewHeight / h); mMinZoom = scale; mMaxZoom = 2*scale; matrix.postScale(scale, scale); matrix.postTranslate((viewWidth - w * scale) / 2F, (viewHeight - h * scale) / 2F); } protected float getValue(Matrix matrix, int whichValue) { matrix.getValues(mMatrixValues); return mMatrixValues[whichValue]; } // Get the scale factor out of the matrix. protected float getScale(Matrix matrix) { return getValue(matrix, Matrix.MSCALE_X); } public float getScale() { return getScale(mSuppMatrix)*mMinZoom; } public float getScaleRate() { return getScale(mSuppMatrix); } public float getMiniZoom() { return mMinZoom; } public float getMaxZoom() { return mMaxZoom; } // Combine the base matrix and the supp matrix to make the final matrix. protected Matrix getImageViewMatrix() { // The final matrix is computed as the concatentation of the base matrix // and the supplementary matrix. mDisplayMatrix.set(mBaseMatrix); mDisplayMatrix.postConcat(mSuppMatrix); return mDisplayMatrix; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); mThisWidth = right - left; mThisHeight = bottom - top; if (image != null) { getProperBaseMatrix(image, mBaseMatrix); setImageMatrix(getImageViewMatrix()); } } protected void zoomTo(float scale, float centerX, float centerY) { if (scale > mMaxZoom) { scale = mMaxZoom; } else if (scale < mMinZoom) { scale = mMinZoom; } float oldScale = getScale(); float deltaScale = scale / oldScale; mSuppMatrix.postScale(deltaScale, deltaScale, centerX, centerY); setImageMatrix(getImageViewMatrix()); center(true, true); } protected void zoomTo(final float scale, final float centerX, final float centerY, final float durationMs) { final float incrementPerMs = (scale - getScale()) / durationMs; final float oldScale = getScale(); final long startTime = System.currentTimeMillis(); mHandler.post(new Runnable() { public void run() { long now = System.currentTimeMillis(); float currentMs = Math.min(durationMs, now - startTime); float target = oldScale + (incrementPerMs * currentMs); zoomTo(target, centerX, centerY); if (currentMs < durationMs) { mHandler.post(this); } } }); } public void zoomTo(float scale) { float cx = getWidth() / 2F; float cy = getHeight() / 2F; zoomTo(scale, cx, cy); } protected void zoomToPoint(float scale, float pointX, float pointY) { float cx = getWidth() / 2F; float cy = getHeight() / 2F; panBy(cx - pointX, cy - pointY); zoomTo(scale, cx, cy); } protected void zoomIn() { zoomIn(SCALE_RATE); } protected void zoomOut() { zoomOut(SCALE_RATE); } protected void zoomIn(float rate) { if (getScale() >= mMaxZoom) { return; // Don't let the user zoom into the molecular level. } if (image == null) { return; } float cx = getWidth() / 2F; float cy = getHeight() / 2F; mSuppMatrix.postScale(rate, rate, cx, cy); setImageMatrix(getImageViewMatrix()); } protected void zoomOut(float rate) { if (image == null) { return; } float cx = getWidth() / 2F; float cy = getHeight() / 2F; // Zoom out to at most 1x. Matrix tmp = new Matrix(mSuppMatrix); tmp.postScale(1F / rate, 1F / rate, cx, cy); if (getScale(tmp) < 1F) { mSuppMatrix.setScale(1F, 1F, cx, cy); } else { mSuppMatrix.postScale(1F / rate, 1F / rate, cx, cy); } setImageMatrix(getImageViewMatrix()); center(true, true); } public void postTranslate(float dx, float dy) { mSuppMatrix.postTranslate(dx, dy); setImageMatrix(getImageViewMatrix()); } float _dy = 0.0f; protected void postTranslateDur(final float dy, final float durationMs) { _dy = 0.0f; final float incrementPerMs = dy / durationMs; final long startTime = System.currentTimeMillis(); mHandler.post(new Runnable() { public void run() { long now = System.currentTimeMillis(); float currentMs = Math.min(durationMs, now - startTime); postTranslate(0, incrementPerMs * currentMs - _dy); _dy = incrementPerMs * currentMs; if (currentMs < durationMs) { mHandler.post(this); } } }); } float _dx = 0.0f; protected void postTranslateXDur(final float dx, final float durationMs) { _dx = 0.0f; final float incrementPerMs = dx / durationMs; final long startTime = System.currentTimeMillis(); mHandler.post(new Runnable() { public void run() { long now = System.currentTimeMillis(); float currentMs = Math.min(durationMs, now - startTime); postTranslate(incrementPerMs * currentMs - _dx, 0); _dx = incrementPerMs * currentMs; if (currentMs < durationMs) { mHandler.post(this); } } }); } protected void panBy(float dx, float dy) { postTranslate(dx, dy); setImageMatrix(getImageViewMatrix()); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { event.startTracking(); return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() && !event.isCanceled()) { if (getScale() > mMinZoom) { zoomTo(mMinZoom); return true; } } return super.onKeyUp(keyCode, event); } public int getImageWidth() { return imageWidth; } public void setImageWidth(int imageWidth) { this.imageWidth = imageWidth; } public int getImageHeight() { return imageHeight; } public void setImageHeight(int imageHeight) { this.imageHeight = imageHeight; } }
看完了這篇文章,相信你對(duì)“Android如何實(shí)現(xiàn)網(wǎng)絡(luò)加載圖片點(diǎn)擊大圖后瀏覽可縮放”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。