DbUtils模块:android中的orm框架,一行代码就可以进行增删改查;
ViewUtils模块:android中的ioc框架,完全注解方式就可以进行UI,资源和事件绑定。
HttpUtils模块:支持同步,异步方式的请求;支持大文件上传,上传大文件不会oom;返回文本内容的请求(默认只启用了GET请求)支持缓存
BitmapUtils模块:加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象;支持加载网络图片和本地图片;内存管理使用lru算法,更好的管理bitmap内存;可配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等...
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
BitmapUtils bitmapUtils = new BitmapUtils(this);
// 加载网络图片
bitmapUtils.display(testImageView, "http://bbs.lidroid.com/static/image/common/logo.png");
// 加载本地图片(路径以/开头, 绝对路径)
bitmapUtils.display(testImageView, "/sdcard/test.jpg");
// 加载assets中的图片(路径以assets开头)
bitmapUtils.display(testImageView, "assets/img/wallpaper.jpg");
// 使用ListView等容器展示图片时可通过PauseOnScrollListener控制滑动和快速滑动过程中时候暂停加载图片
listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils, false, true));
listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils, false, true, customListener));
开始理理项目代码
bitmap_fragment.xml首先看主页面布局--布局只有一个展示数据的ListView
<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/img_list" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout></span>
bitmap_item.xml
<span style="font-size:14px;"><?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/img_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:minHeight="50dp" android:minWidth="50dp" /> <ProgressBar android:id="@+id/img_pb" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="2dp" /> </LinearLayout></span>
BitmapHelp这个是一个单例模式,获取BitmapUtils对象,用来操作加载网络图片
package com.example.xutilsbitmap; import android.content.Context; import com.lidroid.xutils.BitmapUtils; public class BitmapHelp { private BitmapHelp() { } private static BitmapUtils bitmapUtils; /** * BitmapUtils不是单例的 根据需要重载多个获取实例的方法 * * @param appContext * application context * @return */ public static BitmapUtils getBitmapUtils(Context appContext) { if (bitmapUtils == null) { bitmapUtils = new BitmapUtils(appContext); } return bitmapUtils; } }
package com.example.xutilsbitmap; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.TransitionDrawable; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import com.lidroid.xutils.BitmapUtils; import com.lidroid.xutils.HttpUtils; import com.lidroid.xutils.bitmap.BitmapCommonUtils; import com.lidroid.xutils.bitmap.BitmapDisplayConfig; import com.lidroid.xutils.bitmap.PauseOnScrollListener; import com.lidroid.xutils.bitmap.callback.BitmapLoadFrom; import com.lidroid.xutils.bitmap.callback.DefaultBitmapLoadCallBack; import com.lidroid.xutils.exception.HttpException; import com.lidroid.xutils.http.ResponseInfo; import com.lidroid.xutils.http.callback.RequestCallBack; import com.lidroid.xutils.http.client.HttpRequest; public class MainActivity extends Activity { /** * 获取bitmapUtils单例 */ public static BitmapUtils bitmapUtils; private String[] imgSites = { "http://image.baidu.com/", "http://www.22mm.cc/", "http://www.moko.cc/", "http://eladies.sina.com.cn/photo/", "http://www.youzi4.com/" }; private ListView imageListView; private ImageListAdapter imageListAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.bitmap_fragment); // 获取listView控件 imageListView = (ListView) findViewById(R.id.img_list); // 获取bitmapUtils单例 bitmapUtils = BitmapHelp.getBitmapUtils(this); /** * 设置默认的图片展现、加载失败的图片展现 */ bitmapUtils.configDefaultLoadingImage(R.drawable.ic_launcher); bitmapUtils.configDefaultLoadFailedImage(R.drawable.bitmap); bitmapUtils.configDefaultBitmapConfig(Bitmap.Config.RGB_565); // 设置最大宽高, 不设置时根据控件属性自适应. bitmapUtils.configDefaultBitmapMaxSize(BitmapCommonUtils.getScreenSize( this).scaleDown(3)); /** * 滑动时加载图片,快速滑动时不加载图片 com.lidroid.xutils.bitmap.PauseOnScrollListener. * PauseOnScrollListener(TaskHandler taskHandler, boolean pauseOnScroll, * boolean pauseOnFling) */ imageListView.setOnScrollListener(new PauseOnScrollListener( bitmapUtils, false, true)); imageListAdapter = new ImageListAdapter(this); imageListView.setAdapter(imageListAdapter); // 加载url请求返回的图片连接给listview // 这里只是简单的示例,并非最佳实践,图片较多时,最好上拉加载更多... for (String url : imgSites) { loadImgList(url); } imageListView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(MainActivity.this, ImageActivity.class); intent.putExtra("url", imageListAdapter.getItem(position).toString()); startActivity(intent); } }); } /** * 进行网络加载 (HttpMethod method, String url, RequestCallBack<String> callBack) * */ private void loadImgList(String url) { new HttpUtils().send(HttpRequest.HttpMethod.GET, url, new RequestCallBack<String>() { @Override public void onSuccess(ResponseInfo<String> responseInfo) { // 得到的是已打算html内容 Log.e("TAG", "" + responseInfo.result); // 通过正则来获取图片的url地址,并且添加到adapter中 imageListAdapter .addSrc(getImgSrcList(responseInfo.result)); // 通知listview更新数据 imageListAdapter.notifyDataSetChanged(); } @Override public void onFailure(HttpException error, String msg) { Log.e("TAG", "加载失败。。。"); } }); } /** * 得到网页中图片的地址 http://image.baidu.com/ */ public static List<String> getImgSrcList(String htmlStr) { List<String> pics = new ArrayList<String>(); String regEx_img = "<img.*?src=\"http://(.*?).jpg\""; // 图片链接地址 Pattern p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE); Matcher m_image = p_image.matcher(htmlStr); while (m_image.find()) { String src = m_image.group(1); if (src.length() < 100) { pics.add("http://" + src + ".jpg"); } } return pics; } private class ImageListAdapter extends BaseAdapter { private Context mContext; private final LayoutInflater mInflater; private ArrayList<String> imgSrcList; public ImageListAdapter(Context context) { super(); this.mContext = context; mInflater = LayoutInflater.from(context); imgSrcList = new ArrayList<String>(); } /** * 将获取的url地址,添加进来 */ public void addSrc(List<String> imgSrcList) { this.imgSrcList.addAll(imgSrcList); } @Override public int getCount() { return imgSrcList.size(); } @Override public Object getItem(int position) { return imgSrcList.get(position); } @Override public long getItemId(int i) { return i; } @Override public View getView(final int position, View view, ViewGroup parent) { ImageItemHolder holder = null; if (view == null) { view = mInflater.inflate(R.layout.bitmap_item, null); holder = new ImageItemHolder(); holder.imgItem = (ImageView) view.findViewById(R.id.img_item); holder.imgPb = (ProgressBar) view.findViewById(R.id.img_pb); view.setTag(holder); } else { holder = (ImageItemHolder) view.getTag(); } // 初始值进度为0 holder.imgPb.setProgress(0); /** * display参数 (ImageView container, String uri, * BitmapLoadCallBack<ImageView> callBack) */ bitmapUtils.display(holder.imgItem, imgSrcList.get(position), new CustomBitmapLoadCallBack(holder)); return view; } } private class ImageItemHolder { private ImageView imgItem; private ProgressBar imgPb; } /** * 接口 * * @author Administrator * */ public class CustomBitmapLoadCallBack extends DefaultBitmapLoadCallBack<ImageView> { private final ImageItemHolder holder; public CustomBitmapLoadCallBack(ImageItemHolder holder) { this.holder = holder; } /** * 加载过程中,进行进度展示 */ @Override public void onLoading(ImageView container, String uri, BitmapDisplayConfig config, long total, long current) { // 百分比展示进度 this.holder.imgPb.setProgress((int) (current * 100 / total)); } /** * 加载图片完毕 */ @Override public void onLoadCompleted(ImageView imageview, String uri, Bitmap bitmap, BitmapDisplayConfig config, BitmapLoadFrom from) { // 设置图片到listview fadeInDisplay(imageview, bitmap); // 加载完毕,修改进度值 this.holder.imgPb.setProgress(100); } } /** * 动画效果--渐变效果展示 * * @param imageView * @param bitmap */ private void fadeInDisplay(ImageView imageView, Bitmap bitmap) { final TransitionDrawable transitionDrawable = new TransitionDrawable( new Drawable[] { TRANSPARENT_DRAWABLE, new BitmapDrawable(imageView.getResources(), bitmap) }); imageView.setImageDrawable(transitionDrawable); transitionDrawable.startTransition(500); } private static final ColorDrawable TRANSPARENT_DRAWABLE = new ColorDrawable( android.R.color.transparent); }
image.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/big_img" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_gravity="center"/> </LinearLayout>
ImageActivity
package com.example.xutilsbitmap; import android.app.Activity; import android.graphics.Bitmap; import android.os.Bundle; import android.widget.ImageView; import android.widget.Toast; import com.lidroid.xutils.BitmapUtils; import com.lidroid.xutils.bitmap.BitmapCommonUtils; import com.lidroid.xutils.bitmap.BitmapDisplayConfig; import com.lidroid.xutils.bitmap.callback.BitmapLoadCallBack; import com.lidroid.xutils.bitmap.callback.BitmapLoadFrom; import com.lidroid.xutils.bitmap.callback.DefaultBitmapLoadCallBack; /** * Author: wyouflf * Date: 13-10-9 * Time: 下午5:26 */ public class ImageActivity extends Activity { private ImageView bigImage; private BitmapUtils bitmapUtils; private BitmapDisplayConfig bigPicDisplayConfig; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.image); bigImage = (ImageView) findViewById(R.id.big_img); String imgUrl = getIntent().getStringExtra("url"); if (bitmapUtils == null) { bitmapUtils = BitmapHelp.getBitmapUtils(this); } bigPicDisplayConfig = new BitmapDisplayConfig(); // 显示原始图片,不压缩, 尽量不要使用, 图片太大时容易OOM。 //bigPicDisplayConfig.setShowOriginal(true); bigPicDisplayConfig.setBitmapConfig(Bitmap.Config.RGB_565); bigPicDisplayConfig.setBitmapMaxSize(BitmapCommonUtils.getScreenSize(this)); BitmapLoadCallBack<ImageView> callback = new DefaultBitmapLoadCallBack<ImageView>() { @Override public void onLoadStarted(ImageView container, String uri, BitmapDisplayConfig config) { super.onLoadStarted(container, uri, config); Toast.makeText(getApplicationContext(), uri, 300).show(); } @Override public void onLoadCompleted(ImageView container, String uri, Bitmap bitmap, BitmapDisplayConfig config, BitmapLoadFrom from) { super.onLoadCompleted(container, uri, bitmap, config, from); Toast.makeText(getApplicationContext(), bitmap.getWidth() + "*" + bitmap.getHeight(), 300).show(); } }; bitmapUtils.display(bigImage, imgUrl, bigPicDisplayConfig, callback); } }
如下的代码是设置加载图片之前默认的显示图片,加载失败的图片,以及图片的质量参数
/** * 设置默认的图片展现、加载失败的图片展现 */ bitmapUtils.configDefaultLoadingImage(R.drawable.ic_launcher); bitmapUtils.configDefaultLoadFailedImage(R.drawable.bitmap); bitmapUtils.configDefaultBitmapConfig(Bitmap.Config.RGB_565);
/** * 进行网络加载 (HttpMethod method, String url, RequestCallBack<String> callBack) */ private void loadImgList(String url) { new HttpUtils().send(HttpRequest.HttpMethod.GET, url, new RequestCallBack<String>() { @Override public void onSuccess(ResponseInfo<String> responseInfo) { // 得到的是已打算html内容 Log.e("TAG", "" + responseInfo.result); // 通过正则来获取图片的url地址,并且添加到adapter中 imageListAdapter .addSrc(getImgSrcList(responseInfo.result)); // 通知listview更新数据 imageListAdapter.notifyDataSetChanged(); } @Override public void onFailure(HttpException error, String msg) { Log.e("TAG", "加载失败。。。"); } }); }
请求完毕,json或则xml内容后,就利用下面的方法,获取图片地址,并创建集合对象--利用了正则表达式
/** * 得到网页中图片的地址 http://image.baidu.com/ */ public static List<String> getImgSrcList(String htmlStr) { List<String> pics = new ArrayList<String>(); String regEx_img = "<img.*?src=\"http://(.*?).jpg\""; // 图片链接地址 Pattern p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE); Matcher m_image = p_image.matcher(htmlStr); while (m_image.find()) { String src = m_image.group(1); if (src.length() < 100) { pics.add("http://" + src + ".jpg"); } } return pics; }
imageListAdapter .addSrc(getImgSrcList(responseInfo.result));
/** * 将获取的url地址,添加进来 */ public void addSrc(List<String> imgSrcList) { this.imgSrcList.addAll(imgSrcList); }
在adapter里面关键的地方是
/** * display参数 (ImageView container, String uri, * BitmapLoadCallBack<ImageView> callBack) */ bitmapUtils.display(holder.imgItem, imgSrcList.get(position), new CustomBitmapLoadCallBack(holder));
/** * 接口 * * @author Administrator * */ public class CustomBitmapLoadCallBack extends DefaultBitmapLoadCallBack<ImageView> { private final ImageItemHolder holder; public CustomBitmapLoadCallBack(ImageItemHolder holder) { this.holder = holder; } /** * 加载过程中,进行进度展示 */ @Override public void onLoading(ImageView container, String uri, BitmapDisplayConfig config, long total, long current) { // 百分比展示进度 this.holder.imgPb.setProgress((int) (current * 100 / total)); } /** * 加载图片完毕 */ @Override public void onLoadCompleted(ImageView imageview, String uri, Bitmap bitmap, BitmapDisplayConfig config, BitmapLoadFrom from) { // 设置图片到listview fadeInDisplay(imageview, bitmap); // 加载完毕,修改进度值 this.holder.imgPb.setProgress(100); } }
这个是用的一个渐变的效果代码如下
/** * 动画效果--渐变效果展示 * * @param imageView * @param bitmap */ private void fadeInDisplay(ImageView imageView, Bitmap bitmap) { final TransitionDrawable transitionDrawable = new TransitionDrawable( new Drawable[] { TRANSPARENT_DRAWABLE, new BitmapDrawable(imageView.getResources(), bitmap) }); imageView.setImageDrawable(transitionDrawable); transitionDrawable.startTransition(500); } private static final ColorDrawable TRANSPARENT_DRAWABLE = new ColorDrawable( android.R.color.transparent);