最近做android开发的时候遇到读取sdcard下面图片展示,在网上找了很多相关资料,最终得于解决。在这里首先感谢下互联网的朋友们。接下来我把我实现的代码贴出来和大家分享下。由于代码里面的注释写的很清楚。我就不再一一描述了。
package com.zhuyesoft.sgzs.ui; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v4.util.LruCache; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ArrayAdapter; import android.widget.GridView; import android.widget.ImageView; import com.zhuyesoft.sgzs.activity.R; /** * LruCache的流程分析: 我们从第一次进入应用的情况下开始 1 依据图片的Url从LruCache缓存中取图片. * 若图片存在缓存中,则显示该图片;否则显示默认图片 2 因为是第一次进入该界面所以会执行: loadBitmaps(firstVisibleItem, * visibleItemCount); 我们从loadBitmaps()方法作为切入点,继续往下梳理 3 * 尝试从LruCache缓存中取图片.如果在显示即可,否则进入4 4 开启一个异步任务下载图片.下载完成后显示图片,并且将 该图片存入LruCache缓存中 * * 在停止滑动时,会调用loadBitmaps(firstVisibleItem, visibleItemCount) 情况与上类似 */ @SuppressLint("NewApi") public class GridViewAdapter extends ArrayAdapter<String> { private GridView mGridView; // 图片缓存类 private LruCache<String, Bitmap> mLruCache; // GridView中可见的第一张图片的下标 private int mFirstVisibleItem; // GridView中可见的图片的数量 private int mVisibleItemCount; // 记录是否是第一次进入该界面 private boolean isFirstEnterThisActivity = true; private String[] imageUrls; public GridViewAdapter(Context context, int textViewResourceId, String[] objects, GridView gridView) { super(context, textViewResourceId, objects); mGridView = gridView; mGridView.setOnScrollListener(new ScrollListenerImpl()); imageUrls=objects; // 获取应用程序最大可用内存 int maxMemory = (int) Runtime.getRuntime().maxMemory(); // 设置图片缓存大小为maxMemory的1/6 int cacheSize = maxMemory / 6; mLruCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount(); } }; } @Override public View getView(int position, View convertView, ViewGroup parent) { String url = getItem(position); View view; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate( R.layout.activity_view_photo_gridview_item, null); } else { view = convertView; } ImageView imageView = (ImageView) view.findViewById(R.id.imageView); // 为该ImageView设置一个Tag,防止图片错位 imageView.setTag(url); // 为该ImageView设置显示的图片 setImageForImageView(url, imageView); return view; } /** * 为ImageView设置图片(Image) 1 从缓存中获取图片 2 若图片不在缓存中则为其设置默认图片 */ private void setImageForImageView(String imageUrl, ImageView imageView) { Bitmap bitmap = getBitmapFromLruCache(imageUrl); if (bitmap != null) { imageView.setImageBitmap(bitmap); } else { imageView.setImageResource(R.drawable.default_image); } } /** * 将图片存储到LruCache */ public void addBitmapToLruCache(String key, Bitmap bitmap) { if (getBitmapFromLruCache(key) == null) { mLruCache.put(key, bitmap); } } /** * 从LruCache缓存获取图片 */ public Bitmap getBitmapFromLruCache(String key) { return mLruCache.get(key); } /** * 为GridView的item加载图片 * * @param firstVisibleItem * GridView中可见的第一张图片的下标 * * @param visibleItemCount * GridView中可见的图片的数量 * */ private void loadBitmaps(int firstVisibleItem, int visibleItemCount) { try { for (int i = firstVisibleItem; i < firstVisibleItem + visibleItemCount; i++) { String imageUrl = imageUrls[i]; Bitmap bitmap = getBitmapFromLruCache(imageUrl); if (bitmap == null) { bitmap=BitmapFactory.decodeFile(imageUrl); ImageView imageView = (ImageView) mGridView.findViewWithTag(imageUrl); if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } //将从SDCard读取的图片添加到LruCache中 addBitmapToLruCache(imageUrl, bitmap); } else { // 依据Tag找到对应的ImageView显示图片 ImageView imageView = (ImageView) mGridView .findViewWithTag(imageUrl); if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } } } } catch (Exception e) { e.printStackTrace(); } } private class ScrollListenerImpl implements OnScrollListener { /** * * 我们的本意是通过onScrollStateChanged获知:每次GridView停止滑动时加载图片 但是存在一个特殊情况: * 当第一次入应用的时候,此时并没有滑动屏幕的操作即不会调用onScrollStateChanged,但应该加载图片. * 所以在此处做一个特殊的处理. 即代码: if (isFirstEnterThisActivity && visibleItemCount * > 0) { loadBitmaps(firstVisibleItem, visibleItemCount); * isFirstEnterThisActivity = false; } * * ------------------------------------------------------------ * * 其余的都是正常情况. 所以我们需要不断保存:firstVisibleItem和visibleItemCount * 从而便于中在onScrollStateChanged()判断当停止滑动时加载图片 * */ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { mFirstVisibleItem = firstVisibleItem; mVisibleItemCount = visibleItemCount; if (isFirstEnterThisActivity && visibleItemCount > 0) { System.out.println("---> 第一次进入该界面"); loadBitmaps(firstVisibleItem, visibleItemCount); isFirstEnterThisActivity = false; } } /** * GridView停止滑动时下载图片 其余情况下取消所有正在下载或者等待下载的任务 */ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == SCROLL_STATE_IDLE) { loadBitmaps(mFirstVisibleItem, mVisibleItemCount); } } } }
package cc.testlrucache; import android.os.Bundle; import android.widget.GridView; import android.app.Activity; /** * Demo描述: * Android利用LruCache为GridView加载大量本地图片完整示例,防止OOM * * 更多参考: * http://blog.csdn.net/lfdfhl */ public class MainActivity extends Activity { private GridView mGridView; private GridViewAdapter mGridViewAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } private void init(){ mGridView = (GridView) findViewById(R.id.gridView); mGridViewAdapter = new GridViewAdapter(this, 0, ImagesPath.IMAGES_PATH, mGridView); mGridView.setAdapter(mGridViewAdapter); } }
package cc.testlrucache; public class ImagesPath { public final static String DIR="/mnt/sdcard/Test/"; public final static String[] IMAGES_PATH = new String[] { DIR+"a.jpg", DIR+"b.jpg", DIR+"c.jpg", DIR+"d.jpg", DIR+"e.jpg", DIR+"f.jpg", DIR+"g.jpg", DIR+"h.jpg", DIR+"i.jpg", DIR+"j.jpg", DIR+"k.jpg", DIR+"l.jpg", DIR+"m.jpg", DIR+"n.jpg", DIR+"o.jpg", DIR+"p.jpg", DIR+"q.jpg", DIR+"r.jpg", DIR+"s.jpg", DIR+"t.jpg", DIR+"w.jpg", DIR+"x.jpg", DIR+"y.jpg", DIR+"z.jpg", DIR+"za.jpg", DIR+"zb.jpg", DIR+"zc.jpg", DIR+"zd.jpg", DIR+"ze.jpg", DIR+"zf.jpg", DIR+"zg.jpg", DIR+"zh.jpg", DIR+"zi.jpg", DIR+"zj.jpg", DIR+"zk.jpg", DIR+"zl.jpg", DIR+"zm.jpg" }; }
<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" > <GridView android:id="@+id/gridView" android:layout_width="match_parent" android:layout_height="wrap_content" android:columnWidth="100dip" android:gravity="center" android:numColumns="auto_fit" android:layout_marginTop="5dip" android:layout_below="@id/ll_vt_header" android:stretchMode="columnWidth" android:verticalSpacing="10dip" /> </RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:id="@+id/imageView" android:layout_width="100dip" android:layout_height="100dip" android:src="@drawable/default_image" android:layout_centerInParent="true" /> </RelativeLayout>
相关推荐
- **滚动监听**:监听GridView的滚动事件,只在即将可见的item范围内加载图片,实现“滚动即加载”。 - **错误处理**:添加异常处理机制,当图片加载失败时,可以显示占位符或默认图片。 参考链接中的博客文章...
在加载图片时,应根据ImageView的大小进行合适的解码,避免加载全尺寸图片。 4. 使用第三方库:有许多优秀的开源库可以帮助我们更高效地实现图片异步加载,例如Picasso、Glide和Fresco。这些库已经考虑到了许多优化...
在加载图片时,如果一次性加载所有图片到内存中,特别是高分辨率的图片,会迅速消耗大量内存,从而引发OOM。 针对这个问题,我们可以采取以下策略: 1. **使用低分辨率的缩略图**:加载原图前,先将其压缩为适合...
2. 使用BitmapFactory.Options:在加载图片时,利用Options对象设置inSampleSize,进行图片采样率调整,降低图片大小。 3. 内存缓存策略:使用LRUCache或LruCache(Android SDK 16+)进行内存管理,根据缓存大小自动...
3. **使用GridView加载图片** GridView的适配器(如BaseAdapter或ArrayAdapter)需要扩展以包含异步加载图片的功能。在getView()方法中,启动异步任务加载图片,并在图片加载完成后更新ImageView。 4. **缓存策略*...
在异步加载图片的过程中,通常会结合图片缓存技术,如使用内存缓存和磁盘缓存。这样,一旦图片被加载过一次,再次请求时可以从缓存中直接获取,避免了重复加载,提高了用户体验。 5. **图片库或框架**: 实现上述...
在本项目中,“Gridview加载网络图片Andriod源码”提供了实现GridView加载网络图片的功能,无需依赖额外的jar包,这使得项目更轻量且易于维护。 首先,我们需要了解如何在Android中处理网络图片。在Android API 24...
2. 将getView中需要加载的图片添加进堆栈,启动异步线程从栈顶开始加载图片,保证当前显示区域的图片被先显示。 3. 调整Load线程优先级为Thread.NORM_PRIORITY-1,不要和UI线程抢时间片,使滚动更流畅。 该代码用...
以下将详细讨论如何在Android中完美解决GridView异步加载图片和处理大量图片时的内存优化策略。 1. **使用BitmapOptions预估大小** 在加载图片之前,通过`BitmapFactory.Options`的`inJustDecodeBounds`属性可以...
本Demo "Android网络加载图片GridView缓存处理Demo" 主要关注如何高效地从网络加载图片,并利用内存缓存机制来优化性能。在这个项目中,我们使用了两个关键组件:GridView 和 LruCache。 首先,让我们详细了解`...
在这个Demo中,可能会使用其中的一种,它们都能有效地处理图片的缩放、裁剪以及缓存,避免了每次都从网络加载图片,提高用户体验。 点击图片查看大图的实现,通常会弹出一个全屏的`Dialog`或者一个新的`Activity`,...
- 为优化ListView/GridView的滚动性能,使用ViewHolder模式可以复用已创建的视图,减少findViewById()调用,提高性能。 综上所述,"android Gridview 异步加载网络图片"是一个涉及Android UI设计、多线程编程、...
综上所述,加载SD卡中的图片到GridView涉及到Android的基础组件使用、文件操作、图片处理以及性能优化等多个知识点。开发者需要理解Adapter的工作原理,掌握文件系统的操作,以及学会利用各种工具和策略提升用户体验...
android加载大量图片内存溢出的三种解决办法
在GridView中加载图片时结合使用Glide,可以实现快速且高效的图片展示,特别是当需要将图片裁剪为圆形,如作为头像显示时。 首先,我们需要在项目中引入Glide库。在build.gradle模块文件中添加依赖: ```groovy ...
使用Volley加载网络图片,我们需要利用`NetworkImageView`,这是Volley专门为加载图片设计的控件。当图片加载成功时,它会自动将网络图片显示在界面上。 具体实现步骤如下: 1. **添加依赖**:在项目的build....
因此,"gridview的异步加载图片"是解决这个问题的关键技术。异步加载图片可以在后台线程中进行,避免阻塞主线程,提高用户体验。 首先,我们需要理解异步加载的基本原理。在Android中,我们可以使用AsyncTask、...
ListView GridView ViewPager 异步加载网络图片 +缓存+可配置 万能图片加载器 超级顺畅加载显示 使用简单 教程地址:http://blog.csdn.net/zabio/article/details/19836805
在Android开发中,GridView是...通过调整适配器中的逻辑,你还可以实现更多功能,比如显示图片预览、加载网络图片等。记住,关键在于理解GridView的工作原理,以及如何通过适配器与自定义视图协同工作来实现特定需求。
使用UIL,我们可以轻松地在GridView中加载图片,同时处理网络和本地资源。 2. **Picasso**:由Square公司开发的简单易用的图片加载库,自动处理图片的缓存和加载。Picasso支持简单的API调用来显示和转换图片,使得...