看了下ImageLoader框架发表下自己的理解
2016-03-11 10:12
302 查看
**小菜鸟的我发表下对ImageLoader框架用法的部分认识**
大四实习生小菜鸟一枚,最近工作要处理图文页的缓存,是listView列表形式的。在网上搜了搜,发现了许多前辈都推荐用ImageLoader,昨天下载下来看了看理解了下源代码。今天来发表下自己的小认识,不足之处还望前辈批评指正。
首先我在github官网上下载下来了library,导入android studio运行后出现这个界面:
第一步当然是找MainActivity啦,在这里我进去了HomeActivity.
发现了个有趣的现象,这里的点击事件都是在布局文件中的view添加的,然后在代码中构造同名函数并传入View,如果想深入了解为什么传入view .可以参考我上一篇文章:
我的第一篇博客哦
我做的是图文页当然是进去第一个啦,进去后是这个界面:
这个框架基本上想我们所需,把该做的功能都做好了。比如listview滑动时不下载网络网络图片,停止时才更新,etc.
废话少说,我进去ImageListFragment类中瞧了下发现它继承了AbsListViewBaseFragment,而AbsListViewBaseFragment继承了BaseFragment.如果是想了解下怎么让滑动的或者”飞起来”的view做pause动作可以从AbsListViewBaseFragment这个类研究。
而AbsListViewBaseFragment又继承BaeFragment。
基类BaseFragment:
public abstract class BaseFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true); } public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.main_menu, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.item_clear_memory_cache: ImageLoader.getInstance().clearMemoryCache(); return true; case R.id.item_clear_disc_cache: ImageLoader.getInstance().clearDiskCache(); return true; default: return false; } }
}
代码也比较简洁,不过发现这里有些我们新手值得学习的地方,比如为什么构建这个基类?如图:
l还有其他的也类似,它们都能通过右上角点出一个菜单。通过构造基类大大提高了代码的复用性,还有就是它选择的是菜单而不是dialog。我以及我的同事包括我们的老大好像在开发中对菜单的用法没什么意识,看了这个框架的源代码让我在以后的开发中多了一种开发选择。
另外这个类中switch语句的写法同样值得我们新手去学习,在此之前我有思维定式,下意识地认为case语句结尾必须用break跳出,看了这个框架后发现原来还可以这样。在一个方法中写switch语句时,方法的返回参数可以为Boolean值,在每一个case语句末尾把break换成return语句替换感觉更牛逼
让我们回到关键类ImageListFragment。
代码如下:
public class ImageListFragment extends AbsListViewBaseFragment {
public static final int INDEX = 0; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fr_image_list, container, false); listView = (ListView) rootView.findViewById(android.R.id.list); ((ListView) listView).setAdapter(new ImageAdapter(getActivity())); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { startImagePagerActivity(position); } }); return rootView; } @Override public void onDestroy() { super.onDestroy(); AnimateFirstDisplayListener.displayedImages.clear(); } private static class ImageAdapter extends BaseAdapter { private static final String[] IMAGE_URLS = Constants.IMAGES; private LayoutInflater inflater; private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener(); private DisplayImageOptions options; ImageAdapter(Context context) { inflater = LayoutInflater.from(context); options = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.ic_stub) .showImageForEmptyUri(R.drawable.ic_empty) .showImageOnFail(R.drawable.ic_error) .cacheInMemory(true) .cacheOnDisk(true) .considerExifParams(true) .displayer(new CircleBitmapDisplayer(Color.WHITE, 5)) .build(); } @Override public int getCount() { return IMAGE_URLS.length; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { View view = convertView; final ViewHolder holder; if (convertView == null) { view = inflater.inflate(R.layout.item_list_image, parent, false); holder = new ViewHolder(); holder.text = (TextView) view.findViewById(R.id.text); holder.image = (ImageView) view.findViewById(R.id.image); view.setTag(holder); } else { holder = (ViewHolder) view.getTag(); } holder.text.setText("Item " + (position + 1)); ImageLoader.getInstance().displayImage(IMAGE_URLS[position], holder.image, options, animateFirstListener); return view; } } static class ViewHolder { TextView text; ImageView image; } private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener { static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>()); @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { if (loadedImage != null) { ImageView imageView = (ImageView) view; boolean firstDisplay = !displayedImages.contains(imageUri); if (firstDisplay) { FadeInBitmapDisplayer.animate(imageView, 500); displayedImages.add(imageUri); } } } }
}
在这个类里我们可以知道看到鼻祖是怎么使用ImgeLoader的。我只简单提下就是了。
在ListView的适配器中ImageAdapter的构造方法中用DisplayImageOptions配置图片显示的选项,
在getView方法中加载显示图片。
ImageLoader.getInstance().displayImage(IMAGE_URLS[position], holder.image, options, animateFirstListener); 一般我们在实际开发中都喜欢用匿名内部类替代后面的接口写法,仁者见仁,智者见智。源代码的静态类写法我们不妨也可以有个意识。它是创建了一个实现ImageLoadingListener接口的子类SimpleImageLoadingListener,这个子类都是空实现了接口的四个载入方法。
今天只是粗浅地谈谈我对这个框架部分用法的总结,框架的设计原理以及代码有待慢慢领悟参透,前辈写的源代码分析代码也是很好。大家可以参考下:
大神写的
相关文章推荐
- 学习进度条
- iOS学习之UINavigationController
- c中使用gets() 提示warning: this program uses gets(), which is unsafe.
- php strpos返回字符串首次出现的位置
- BLE 广播数据解析
- 做一个合格的程序猿之浅析Spring IoC源码(六)BeanFactoryPostProcessor
- Categroy实例
- 【经典转载】Linux进程学习系列之六 进程控制函数之exec()函数的学习
- Socket通讯实例-基本Socket
- 解决setOnItemClickListener无响应的bug
- java进度条代码
- .NET 程序员十种必备工具
- Android项目开发(1)-登录页面知识总结
- IOS开发 代码获取当前APP的版本号
- 添加长时间监听事件 要点:监听的位置和监听事件名称,本案例用setonlongclicklistener事件
- JSON example
- DOS窗口下找到占用8080端口的进程,并且将该进程结束
- 工具的使用——windows操作系统的使用(三)
- GitHub前100的开源库,非常实用
- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path