看了下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,这个子类都是空实现了接口的四个载入方法。
今天只是粗浅地谈谈我对这个框架部分用法的总结,框架的设计原理以及代码有待慢慢领悟参透,前辈写的源代码分析代码也是很好。大家可以参考下:
大神写的

1 0
原创粉丝点击