这是我写的第一篇博客。
本人刚学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空间展示图片那样,能左右滑动和手势对图片的缩放。