作为比较成熟的流行框架,XUtils中的BitmapUtils部分为我们加载照片提供了很大方便,他集成了LRUCache和DiskLruCache缓存机制,在很大程度上避免了我们在加载较多照片时出现的OOM异常,这篇博客我们从使用的角度学习下BitmapUtils的用法,下一篇将从源码的角度带你真正了解BitmapUtils;
我使用BitmapUtils实现了一个照片墙的功能,先上效果图:
其实实现挺简单的,下面详细解释一下:
定义Activity显示布局activity_main.xml:
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <GridView android:id="@+id/photo_wall" android:layout_width="match_parent" android:layout_height="match_parent" android:columnWidth="100dp" android:gravity="center" android:horizontalSpacing="1dp" android:numColumns="auto_fit" android:stretchMode="columnWidth" android:verticalSpacing="1dp" > </GridView> </RelativeLayout>很简单,就只有一个GridView用于显示照片而已了;
每张照片的显示布局gridview.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/photo" android:layout_width="150dp" android:layout_height="150dp" android:layout_centerInParent="true" android:scaleType="fitXY" /> </LinearLayout>也看出来只有一个ImageView而已啦;
接着继承BaseAdapter来实现一个用于显示数据到GridView上面的Adapter:
public class GridViewAdapter extends BaseAdapter{ public LayoutInflater inflater; public String[] imageUrls; public BitmapUtils bitmapUtils; public GridViewAdapter(Context context,String[] imageUrls,BitmapUtils bitmapUtils) { inflater = LayoutInflater.from(context); this.imageUrls = imageUrls; this.bitmapUtils = bitmapUtils; } @Override public int getCount() { return imageUrls.length; } @Override public String getItem(int position) { return imageUrls[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { String currStr = getItem(position); View view; ViewHolder holder; if(convertView == null) { view = inflater.inflate(R.layout.gridview, null); holder = new ViewHolder(); holder.imageView = (ImageView) view.findViewById(R.id.photo); view.setTag(holder); }else { view = convertView; holder = (ViewHolder) view.getTag(); } //为防止图片出现乱序,对每个ImageView进行绑定设置 holder.imageView.setTag(currStr); //设置默认的显示图片 holder.imageView.setImageResource(R.drawable.empty_photo); showBitmapToImageView(currStr, holder.imageView); return view; } /** * 设置Bitmap图片到ImageView上面 * @param url * @param imageView */ public void showBitmapToImageView(String url,ImageView imageView) { bitmapUtils.display(imageView,url); } static class ViewHolder { ImageView imageView; } }最关键的部分当然就是getView了,核心代码也就只有第47行的showBitmapToImageView这个函数啦,查看这个函数的实现,也只有一句话而已,调用BitmapUtils对象的display方法,传入的参数分别是所要请求图片的url,以及所要显示图片的ImageView啦,具体源码到底在这个函数中做了什么我们下一篇介绍;
在Activity中获得GridView实例,并且绑定数据适配器;
public class MainActivity extends Activity { public GridView gridView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gridView = (GridView) findViewById(R.id.photo_wall); String filePath = Utils.getDiskCacheDir(this, "bitmap"); File directory = new File(filePath); if(!directory.exists()) { directory.mkdirs(); } BitmapUtils bitmapUtils = new BitmapUtils(this, filePath); GridViewAdapter adapter = new GridViewAdapter(this, Utils.imageUrls, bitmapUtils); gridView.setAdapter(adapter); } }可以看到在创建BitmapUtils对象的时候,我们生成了存储DiskLruCache缓存文件的SD卡路径,具体是在Utils中的getDiskCacheDir中实现的:
/** * 获取磁盘缓存的存储路径 * @param context * @param uniqueName * @return */ public static String getDiskCacheDir(Context context,String uniqueName) { String filePath = ""; if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { //表示SD卡存在或者不可移除 filePath = context.getExternalCacheDir().getPath();//获得缓存路径 }else { filePath = context.getCacheDir().getPath(); } return filePath+File.separator+uniqueName; }最后不要忘记添加访问网络以及SD卡的权限:
<uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
至此,我们利用BitmapUtils实现的照片墙讲解结束,其实真正意义上的核心代码就一句话,就是调用BitmapUtils的display函数而已,不得不佩服大神的牛B啊!!!!!
点击下载源码!!!!!