看了下ImageLoader框架发表下自己的理解
来源:互联网 发布:倩女幽魂mac可以玩吗 编辑:程序博客网 时间:2024/05/21 07:08
**小菜鸟的我发表下对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);}@Overridepublic 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;@Overridepublic 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;}@Overridepublic 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,这个子类都是空实现了接口的四个载入方法。
今天只是粗浅地谈谈我对这个框架部分用法的总结,框架的设计原理以及代码有待慢慢领悟参透,前辈写的源代码分析代码也是很好。大家可以参考下:
大神写的
- 看了下ImageLoader框架发表下自己的理解
- 今天看了网络编程的基础孙鑫写的稍微给自己理解到得东西做了下总结!
- 自己看别人看了没用,UNICODE下连接数据库
- 设计自己的ImageLoader图片加载框架
- 终于可以发表自己的文章了!
- 【行为模式】记录 (自己简短的理解,感觉理解了就记录下)
- 看解放军练车,想想自己的技术也该提高下了。
- 就是发表的下积分
- 看了下 ROR
- 刚看了个人想用sql实现父联表的树形实现,看了下,自己用sql2000的语法写了个。。
- 看了下主要的东西
- 看了半小时的MVC,总结下
- 敏友的【敏捷个人】有感(4): 发表下个人感言,指导自己的人生
- 今天闲下来,网上看了很多程序员的人生历程,回顾下自己的职业生涯,感慨一下。
- 在MOP看到深圳的English Corner赶紧看下,并按时间整理了一下 方便自己找
- 看了下分析的不错,就记了下来
- caffe框架下添加自己的MFC程序(下)
- ImageLoader显示文件夹下的图片
- assert()函数用法总结
- 做一个合格的程序猿之浅析Spring IoC源码(六)BeanFactoryPostProcessor
- LuaPlus学习
- Android-BaseLine框架初识之如何使用(二)
- MAX方法
- 看了下ImageLoader框架发表下自己的理解
- ThinkPad E450 10.11 驱动HD4400的注意即解决方法
- has_key or in
- docker 学习笔记4
- onclientclick和onclick区别
- 何值会被判断为false
- 设置平铺的方式拉伸图片
- Android笔记
- 剑指offer-从上往下打印二叉树