在很多应用中,比如微信的朋友圈,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