android 图片下载、放大缩小

这是我写的第一篇博客。

本人刚学android没多久,写的博里面肯定有错误,希望走过路过的能指出,大家共同进步。

行了,废话不多说,这篇博客主要是记录一下android图片的下载,还有viewPager里能实现对图片的放大和缩小,这里主要是用到了第三方工具,分别是imageload和photoview,只要项目涉及到图片,那么这两个好东西能帮我们减轻不少压力。

1.用普通方法和imageload从网络获取图片

activity_main.xml  其中第三个按钮是跳转到photoview界面

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical" >
    
    <LinearLayout 
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:orientation="vertical"
        android:layout_weight="1"
        >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/orinaryButton"
        android:text="点击从网络获取图片(一般方法)" />
    <ImageView 
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:id="@+id/showImageByOrinary"
        />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageLoadButton"
        android:text="点击从网络获取图片(用imageload)" />
    <ImageView 
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:id="@+id/showImageByImageLoad"
        />
    </LinearLayout>
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/toBigImage"
        android:text="跳转到图片放大界面"
        />
</LinearLayout>

在我们的MainActivity中的代码是

public class MainActivity extends Activity implements OnClickListener {

	private Button orinaryButton; //用普通方法从网络获取图片
	private Button imageLoadButton; //用imageload从网络获取图片
	private Button toBigImage;  //页面跳转按钮
	private ImageView showImageByOrinary; //用普通方法从网络获取图片待展示的ImageView
	private ImageView showImageByImageLoad; //用imageload从网络获取图片待展示的ImageView
	private String urlPath = "http://www.baidu.com/img/baidu_sylogo1.gif";
	private ProgressDialog dialog;
	private Context context;
	private Bitmap bitmap;
	private DisplayImageOptions options;
	private ImageLoader imageLoader;
	//LoadImageTask子线程完成后通知handler更新UI
	private Handler orinaryHandler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if(msg.what == 0){
				showImageByOrinary.setImageBitmap(bitmap);
				dialog.dismiss(); //清除提示
			}else if(msg.what == 1){
				Toast.makeText(context,"下载失败...", Toast.LENGTH_LONG).show();
			}
		}
	};
	//ImageLoadTask子线程完成后通知handler更新UI
	private Handler imageLoadHandler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if(null == bitmap){
				Toast.makeText(context, "下载失败...", Toast.LENGTH_LONG).show();
			}else{
				showImageByImageLoad.setImageBitmap(bitmap);
				dialog.dismiss(); //清除提示
			}
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		context = this; 
		orinaryButton = (Button) this.findViewById(R.id.orinaryButton);
		imageLoadButton = (Button) this.findViewById(R.id.imageLoadButton);
		toBigImage = (Button) this.findViewById(R.id.toBigImage);
		showImageByOrinary = (ImageView) this.findViewById(R.id.showImageByOrinary);
		showImageByImageLoad = (ImageView) this.findViewById(R.id.showImageByImageLoad);
		orinaryButton.setOnClickListener(this);
		imageLoadButton.setOnClickListener(this);
		toBigImage.setOnClickListener(this);
		//以下都是对imageload的初始化与设置
		options = new DisplayImageOptions.Builder()  
        .showImageForEmptyUri(R.drawable.ic_launcher)  
        .showImageOnFail(R.drawable.ic_launcher)  
        .resetViewBeforeLoading(true)  
        .cacheOnDisc(true)  
        .imageScaleType(ImageScaleType.EXACTLY)  
        .displayer(new FadeInBitmapDisplayer(300))  
        .build();  
	    imageLoader = ImageLoader.getInstance();
		imageLoader.init(ImageLoaderConfiguration.createDefault(context));
		
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.orinaryButton:
			dialog = ProgressDialog.show(context, "提示", "玩命下载中...", true, false);
			new Thread(new LoadImageTask()).start();
			break;
		case R.id.imageLoadButton:
			dialog = ProgressDialog.show(context, "提示", "玩命下载中...", true, false);
			new Thread(new ImageLoadTask()).start();
			break;
		case R.id.toBigImage:
			Intent intent = new Intent(context, BigImageActivity.class);
			startActivity(intent);
			break;
		default:
			break;
		}
		
	}

	/**
	 * 开启一个线程访问去下载图片
	 * @author c_fei
	 *
	 */
	class LoadImageTask implements Runnable{
		Message message =  Message.obtain();//这种方法减少了内存的开销   尽量不要 new  
		@Override
		public void run() {
			URL url;
			try {
				url = new URL(urlPath);
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
		        conn.setConnectTimeout(5 * 1000);  
		        conn.setRequestMethod("GET");  
		        InputStream inStream = conn.getInputStream();  
		        if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){  
		             bitmap = BitmapFactory.decodeStream(inStream);
		             message.what = 0;
		        }  
			} catch (Exception e) {
				message.what = 1;
				e.printStackTrace();
			} finally{
				 orinaryHandler.sendMessage(message);
			} 
	        
		}
		
	}
	
	/**
	 * 用imageload下载图片  
	 * @author c_fei
	 *
	 */
	class ImageLoadTask implements Runnable{
		@Override
		public void run() {
			bitmap = imageLoader.loadImageSync(urlPath, options);
			imageLoadHandler.sendEmptyMessage(0);
		}
		
	}
在这个类中,特别要注意几个地方,连接网络一定要开辟新的线程,如果是在主线程中可能会报ANR异常,但更新界面一定是在主线程中。

2.photoview实现对图片的缩放

photoview能很好地对图片进行缩放,图片下面的索引是我自己写的,只是为了一个良好的用户体验。

activity_big_image.xml中的代码是

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    android:orientation="vertical" >

    <com.example.csdn_image.BigImageViewPager 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:id="@+id/showBigImageViewPager"
        />
    <RelativeLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:gravity="center_horizontal"
        >
        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/showIndex"
            android:paddingBottom="2dp"
            android:textColor="@android:color/white"
         />
    </RelativeLayout>
    
</LinearLayout>

大家可以看到,viewpager被重写了,是的,这是为了避免手势滑动时候产生异常,重写的代码如下

public class BigImageViewPager extends ViewPager {

	public BigImageViewPager(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}
	
	//这个构造方法必须有要不然xml中无法加载 会报错
	public BigImageViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
	//这个方法是为了避免手势滑动的时候产生异常
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		try {
			return super.onInterceptTouchEvent(ev);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			return false;
		}
	}
}

其实,为什么要重写这两个方法,我谷歌了良久,也没有找到答案,我猜想可能是android对事件的处理机制有关,求大神解答。

好了,在xml中的代码已经写好了,在Activity中该怎么写呢,以下是代码

public class BigImageActivity extends Activity {

	private BigImageViewPager bigImageViewPager; //有图片放大功能的ViewPager
	private TextView showIndex; //当前图片索引
	private ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(); //存储下载的bitmap
	private ArrayList<String> urls; //存储待下载图片的集合
	private DisplayImageOptions options;
	private ImageLoader imageLoader;
	private Context context;
	private Bitmap bitmap;
	private GetBitmaps getBitmaps;
	private Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			bigImageViewPager.setAdapter(new BigImageAdapter());
		}
		
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);//取消标题栏
		setContentView(R.layout.activity_big_image);
		context = this;
		bigImageViewPager = (BigImageViewPager) this.findViewById(R.id.showBigImageViewPager);
		showIndex = (TextView) this.findViewById(R.id.showIndex);
		options = new DisplayImageOptions.Builder()  
        .showImageForEmptyUri(R.drawable.ic_launcher)  
        .showImageOnFail(R.drawable.ic_launcher)  
        .resetViewBeforeLoading(true)  
        .cacheOnDisc(true)  
        .imageScaleType(ImageScaleType.EXACTLY)  
        .displayer(new FadeInBitmapDisplayer(300))  
        .build();  
	    imageLoader = ImageLoader.getInstance();
		imageLoader.init(ImageLoaderConfiguration.createDefault(context));
		
		
		showIndex.setText("1/1");//默认当前只有一张图片 并且当前在显示
		getURLData();
		new Thread(new GetBitmaps()).start();
		bigImageViewPager.setOnPageChangeListener(new OnPageChangeListener() {
			@Override
			public void onPageSelected(int arg0) {
				showIndex.setText(arg0+1+"/"+urls.size());
			}
			
			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onPageScrollStateChanged(int arg0) {
				// TODO Auto-generated method stub
				
			}
		});
	}

	/**
	 * 向urls添加待下载图片路径
	 * @return
	 */
	private ArrayList<String>  getURLData(){
		urls = new ArrayList<String>();
		urls.add("http://www.baidu.com/img/baidu_sylogo1.gif");
		urls.add("http://www.baidu.com/img/baidu_sylogo1.gif");
		urls.add("http://www.baidu.com/img/baidu_sylogo1.gif");
		return urls;
	}
	
	/**
	 * 向bitmaps添加下载完成后的Bitmap
	 * 
	 */
	class GetBitmaps implements Runnable{
		@Override
		public void run() {
			if(null!=urls && urls.size()>0){
				for(int i=0;i<urls.size();i++){
					bitmap = imageLoader.loadImageSync(urls.get(i), options);
					bitmaps.add(bitmap);
				}
			}
			handler.sendEmptyMessage(0);
		}
		
	}
	
	
	/**
	 * 
	 * @author c_fei
	 *
	 */
	public class BigImageAdapter extends PagerAdapter{
		
		@Override
		public View instantiateItem(ViewGroup container, int position) {
			Bitmap  bitmap = bitmaps.get(position);
			BigImagePhotoView photoView = null;
			if(null != bitmap){
				photoView = new BigImagePhotoView(container.getContext());
				photoView.setImage(bitmap);
			}
			container.addView(photoView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
			return photoView;
		}
		
		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			container.removeView((View) object);
		}
		
		@Override
		public boolean isViewFromObject(View view, Object object) {
			return view == object;
		}

		@Override
		public int getCount() {
			return bitmaps.size();
		}
		
	}
	
	/**
	 * 当页面销毁时  销毁getBitmaps线程
	 */
	@Override
	protected void onDestroy() {
		super.onDestroy();
		handler.removeCallbacks(getBitmaps);
	}
}

这段代码简单介绍一下,首先是找到各个控件,然后对imageload的初始化,紧接着开辟线程去加载图片资源,再然后对viewpager设置适配器。猛的一看BigImageAdapter跟我们平常写的差不多,但你看仔细了,里面多了一个类叫BigImagePhotoView,这个类是干嘛呢?这其实就是photoview能对imageview实现缩放的奥秘所在。photoview要传的参数是Bitmap类型,所以我用的imageload.loadImageSyn方法,这样能得到Bitmap对象,放在bitmaps集合里,当然了imageload重载了很多优秀的方法,大家有时间可以看一下。

以下是BigImagePhotoView类的代码,他继承了PhotoView,主要是为了初始化imageview。

public class BigImagePhotoView extends PhotoView{

	public BigImagePhotoView(Context context) {
		super(context);
	}
	
    /**
     * 初始化ImageView图片
     * @param bitmap
     */
    public void setImage(Bitmap bitmap) {
        super.setImageBitmap(bitmap);
        if (null != mAttacher) {
            mAttacher.update();
        }
    }
}

最后记得要在AndroidManifest.xml中添加权限

<uses-permission android:name="android.permission.INTERNET" />


主要的代码已经贴出来了,大家可以运行一下看看效果。

效果:由于我还不知道怎么制作gif'动态图,所以图片就先不贴出来了。在这里先说一下,MainActivity运行之后很简单,点击按钮,就直接从网络下载了,BigImageActivity运行之后类似于QQ空间展示图片那样,能左右滑动和手势对图片的缩放。



点击下载源码




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值