第二講--------縮略圖放大

            在很多應用中,比如微信的朋友圈,QQ的空間,每條動態都會有很多圖片,這些圖片都是一些縮略圖,點擊後得到原圖。如果細心的同學可能會注意到QQ空間裏點擊圖片時,只有一個黑色背景和一個下載百分比進度背景,而微信下載大圖時會把縮略圖作爲背景放在後面。

         這一講就完成將縮略圖作爲背景,然後下載原圖。

        整個過程分爲3三步

        1、顯示下載完成之前的提示正在下載頁面

        2、線程從後臺下載圖片並存儲

        3、下載完成後,將提示界面換成大圖界面

        先上程序截圖吧,進去的主界面,很簡單,只有兩個按鈕,按測試按鈕直接進入測試,因爲對下載的大圖進行了緩存,所以要重新測試的時候需要先清除原來緩存好的圖片

     

按測試之後,進入下載提醒界面

       

下載完成後,大圖可以放大、縮小、放大後可以左右移動

              


        首先下載是個耗時的過程,上一講剛講過後臺耗時操作的處理,不過這裏要用那個類的升級版。因爲上一講講的那個下載過程中是不帶UI的,所以稍微做了一下修改,主要代碼如下,我每篇文章都會帶小程序的,xml文件就不放上來了。

 

      

public abstract class ProgressDialogHandle {
    private Context mContext;
    private Dialog mDialog;
    private static final String THREAD_NAME = "dataprocess_thread";
    private static final int UPDATE = 1;
    protected static final int DISMISS = 2;
    protected static final int INVALIDEUSER = 3;
    private HttpURLConnection conn;
    private Bitmap backgound;

    public ProgressDialogHandle(Context context) {
        this.mContext = context;
    }

    public ProgressDialogHandle(Context context, HttpURLConnection conn) {
        this.mContext = context;
        this.conn = conn;
    }

    Handler messageHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case UPDATE:

                break;
            case DISMISS:
                try {
                    /* 執行這裏的時候,判斷對話框是否已經存在,不然直接執行dismiss可能會出現異常 */
                    if (mDialog != null && mDialog.isShowing()) {
                        mDialog.dismiss();
                    }
                } catch (Exception e) {

                } finally {
                    updateUI();
                }
                break;
            default:
                break;
            }

        }
    };

    public void show() {
        if(mDialog == null){
            mDialog = getProgressDialog(mContext, backgound);
            mDialog.setOnCancelListener(new OnCancelListener() {

                @Override
                public void onCancel(DialogInterface dialog) {
                    try {
                        if (conn != null) {
                            conn.disconnect();
                            conn = null;
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        mDialog.show();
        new Thread(THREAD_NAME) {
            public void run() {
                try {
                    handleData();
                }
                catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    Message.obtain(messageHandler, DISMISS).sendToTarget();
                }
            };
        }.start();
    }

    public void dismiss() {
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
        }
    }

    public void setBackground(Bitmap backgound) {
        this.backgound = backgound;
    }

    @SuppressLint("NewApi")
    
    public static Dialog getProgressDialog(Context context, Bitmap bm) {
        final Dialog dialog = new Dialog(context, R.style.progress_dialog);
        dialog.setContentView(R.layout.progress_dialog_view);
        if (bm != null) {
            ImageView iv = (ImageView) dialog.findViewById(R.id.progress_iv);
            iv.setImageBitmap(bm);
        }
        dialog.setCanceledOnTouchOutside(false);
        return dialog;
    }

    public abstract void handleData() throws JSONException, IOException,
            Exception;

    public abstract String initialContent();

    public abstract void updateUI();
}

在使用的時候注意:要把縮略圖做背景圖顯示的話,在調用show方法開始執行下載任務之前要先調用setBackgroud方法設置背景圖片

大圖瀏覽主類

package com.yixuan;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONException;

import com.example.handlertest.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * 大圖預覽
 * 功能描述:一般我們瀏覽一個應用,別人發佈的狀態或新聞都會有很多配圖,
 *          我們點擊圖片時可以瀏覽大圖,這張大圖一般可以放大,放大到超過屏幕後
 *          可以移動
 *需要從activity的Intent傳參數過來
 * 傳入參數:url  大圖下載地址
 *          smallPath 縮略圖存在本地的地址
 * @author Administrator
 *
 */
public class PicturePreviewActivity extends Activity{
	private ImageView zoomView;
	private Context ctx;
	private GestureDetector gestureDetector;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_picture_preview);
		ctx = this;
		zoomView = (ImageView) findViewById(R.id.zoom_view);
		/*大圖的下載地址*/
		final String url = getIntent().getStringExtra("url");
		/*縮略圖存儲在本地的地址*/
		final String smallPath = getIntent().getStringExtra("smallPath");
		DisplayMetrics metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metrics);
		final int widthPixels = metrics.widthPixels;
		final int heightPixels = metrics.heightPixels;
		if (!TextUtils.isEmpty(url)) {
			ProgressDialogHandle handle = new ProgressDialogHandle(this) {
				Bitmap bitmap = null;

				@Override
				public void handleData() throws JSONException, IOException,
						Exception {
					bitmap = getBitMapFromUrl(url);
				}

				@Override
				public String initialContent() {
					return null;
				}

				@Override
				public void updateUI() {
					if (bitmap != null) {
						recycle();
						zoomView.setImageBitmap(zoomBitmap(bitmap, widthPixels,
								heightPixels));
					} else {
						Toast.makeText(ctx, R.string.download_failed,
								Toast.LENGTH_LONG).show();
					}
				}

			};
			handle.setBackground(BitmapFactory.decodeFile(smallPath));
			handle.show();
		}
		gestureDetector = new GestureDetector(this,
				new GestureDetector.SimpleOnGestureListener() {
					@Override
					public boolean onFling(MotionEvent e1, MotionEvent e2,
							float velocityX, float velocityY) {
						float x = e2.getX() - e1.getX();
						if (x > 0) {
							prePicture();
						} else if (x < 0) {

							nextPicture();
						}
						return true;
					}
				});
	}

	protected void nextPicture() {
		// TODO Auto-generated method stub

	}

	protected void prePicture() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onResume() {
		super.onResume();
		recycle();
	}

	public void recycle() {
		if (zoomView != null && zoomView.getDrawable() != null) {
			BitmapDrawable bitmapDrawable = (BitmapDrawable) zoomView
					.getDrawable();
			if (bitmapDrawable != null && bitmapDrawable.getBitmap() != null
					&& !bitmapDrawable.getBitmap().isRecycled())

			{
				bitmapDrawable.getBitmap().recycle();
			}
		}
	}

	public Bitmap getBitMapFromUrl(String url) {
		Bitmap bitmap = null;
		URL u = null;
		HttpURLConnection conn = null;
		InputStream is = null;
		try {
			u = new URL(url);
			conn = (HttpURLConnection) u.openConnection();
			is = conn.getInputStream();
			bitmap = BitmapFactory.decodeStream(is);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (is != null) {
					is.close();
				}

			} catch (IOException e) {
				e.printStackTrace();
			}
			conn.disconnect();
		}
		return bitmap;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		return gestureDetector.onTouchEvent(event);
	}


	/**
	 * Resize the bitmap
	 * 
	 * @param bitmap
	 * @param width
	 * @param height
	 * @return
	 */
	public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {
		if (bitmap == null)
			return bitmap;
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		Matrix matrix = new Matrix();
		float scaleWidth = ((float) width / w);
		float scaleHeight = ((float) height / h);
		if (scaleWidth < scaleHeight) {
			matrix.postScale(scaleWidth, scaleWidth);
		} else {
			matrix.postScale(scaleHeight, scaleHeight);
		}
		Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
		return newbmp;
	}
}

主類

package com.yixuan;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONException;

import com.example.handlertest.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * 大圖預覽 功能描述:一般我們瀏覽一個應用,別人發佈的狀態或新聞都會有很多配圖, 我們點擊圖片時可以瀏覽大圖,這張大圖一般可以放大,放大到超過屏幕後
 * 可以移動 需要從activity的Intent傳參數過來 傳入參數:url 大圖下載地址 smallPath 縮略圖存在本地的地址
 * 
 * @author Administrator
 * 
 */
public class PicturePreviewActivity extends Activity {
	private ImageView zoomView;
	private Context ctx;
	private GestureDetector gestureDetector;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_picture_preview);
		ctx = this;
		zoomView = (ImageView) findViewById(R.id.zoom_view);
		/* 大圖的下載地址 */
		final String url = getIntent().getStringExtra("url");
		/* 縮略圖存儲在本地的地址 */
		final String smallPath = getIntent().getStringExtra("smallPath");
		DisplayMetrics metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metrics);
		final int widthPixels = metrics.widthPixels;
		final int heightPixels = metrics.heightPixels;
		File bigPicFile = new File(getLocalPath(url));
		if (bigPicFile.exists()) {/* 如果已經下載過了,直接從本地文件中讀取 */
			zoomView.setImageBitmap(zoomBitmap(
					BitmapFactory.decodeFile(getLocalPath(url)), widthPixels,
					heightPixels));
		} else if (!TextUtils.isEmpty(url)) {
			ProgressDialogHandle handle = new ProgressDialogHandle(this) {
				Bitmap bitmap = null;

				@Override
				public void handleData() throws JSONException, IOException,
						Exception {
					bitmap = getBitMapFromUrl(url);
				}

				@Override
				public String initialContent() {
					return null;
				}

				@Override
				public void updateUI() {
					if (bitmap != null) {
						recycle();
						savePhotoToSDCard(bitmap, getLocalPath(url));
						zoomView.setImageBitmap(zoomBitmap(bitmap, widthPixels,
								heightPixels));
					} else {
						Toast.makeText(ctx, R.string.download_failed,
								Toast.LENGTH_LONG).show();
					}
				}

			};
			handle.setBackground(BitmapFactory.decodeFile(smallPath));
			handle.show();
		}
		gestureDetector = new GestureDetector(this,
				new GestureDetector.SimpleOnGestureListener() {
					@Override
					public boolean onFling(MotionEvent e1, MotionEvent e2,
							float velocityX, float velocityY) {
						float x = e2.getX() - e1.getX();
						if (x > 0) {
							prePicture();
						} else if (x < 0) {

							nextPicture();
						}
						return true;
					}
				});
	}

	protected void nextPicture() {
		// TODO Auto-generated method stub

	}

	protected void prePicture() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onResume() {
		super.onResume();
		recycle();
	}

	public void recycle() {
		if (zoomView != null && zoomView.getDrawable() != null) {
			BitmapDrawable bitmapDrawable = (BitmapDrawable) zoomView
					.getDrawable();
			if (bitmapDrawable != null && bitmapDrawable.getBitmap() != null
					&& !bitmapDrawable.getBitmap().isRecycled())

			{
				bitmapDrawable.getBitmap().recycle();
			}
		}
	}

	public Bitmap getBitMapFromUrl(String url) {
		Bitmap bitmap = null;
		URL u = null;
		HttpURLConnection conn = null;
		InputStream is = null;
		try {
			u = new URL(url);
			conn = (HttpURLConnection) u.openConnection();
			is = conn.getInputStream();
			bitmap = BitmapFactory.decodeStream(is);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (is != null) {
					is.close();
				}

			} catch (IOException e) {
				e.printStackTrace();
			}
			conn.disconnect();
		}
		return bitmap;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		return gestureDetector.onTouchEvent(event);
	}

	/**
	 * Resize the bitmap
	 * 
	 * @param bitmap
	 * @param width
	 * @param height
	 * @return
	 */
	public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {
		if (bitmap == null)
			return bitmap;
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		Matrix matrix = new Matrix();
		float scaleWidth = ((float) width / w);
		float scaleHeight = ((float) height / h);
		if (scaleWidth < scaleHeight) {
			matrix.postScale(scaleWidth, scaleWidth);
		} else {
			matrix.postScale(scaleHeight, scaleHeight);
		}
		Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
		return newbmp;
	}

	public static String getLocalPath(String url) {
		String fileName = "temp.png";
		if (url != null) {
			if (url.contains("/")) {
				fileName = url
						.substring(url.lastIndexOf("/") + 1, url.length());
			}
			fileName = fileName.replaceAll("&", "").replaceAll("%", "")
					.replaceAll("?", "");
		}
		return Environment.getExternalStorageDirectory() + fileName;
	}

	/**
	 * Save image to the SD card
	 * 
	 * @param photoBitmap
	 * @param photoName
	 * @param path
	 */
	public static void savePhotoToSDCard(Bitmap photoBitmap, String fullPath) {
		if (checkSDCardAvailable()) {
			File file = new File(fullPath);
			if (!file.getParentFile().exists()) {
				file.getParentFile().mkdirs();
			}

			File photoFile = new File(fullPath);
			FileOutputStream fileOutputStream = null;
			try {
				fileOutputStream = new FileOutputStream(photoFile);
				if (photoBitmap != null) {
					if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100,
							fileOutputStream)) {
						fileOutputStream.flush();
					}
				}
			} catch (FileNotFoundException e) {
				photoFile.delete();
				e.printStackTrace();
			} catch (IOException e) {
				photoFile.delete();
				e.printStackTrace();
			} finally {
				try {
					fileOutputStream.close();
					photoBitmap.recycle();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static boolean checkSDCardAvailable() {
		return android.os.Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED);
	}

}

示例程序下載地址:http://download.csdn.net/download/u010047390/8466837



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章