您的位置:首页 > 其它

获取手机所有图片并显示

2015-12-02 11:20 309 查看
在网上查了一些资料,废了很大功夫才把这个功能实现,有一些细节还是需要注意的,废话不多说开始讲解今天的内容。
先一睹为快,看一下最终的效果图



显示列表即用到Listview,新建布局文件mylist 如下:
<?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"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp">
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
</ListView>

</LinearLayout>


接着listview内部图片和内容显示的布局simple_item

<?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="horizontal" >

<ImageView
android:id="@+id/img"
android:layout_width="50dp"
android:layout_height="50dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="3dp">
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
/>
<TextView
android:id="@+id/info"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="10sp"
android:paddingTop="5dp"
/>
</LinearLayout>
</LinearLayout>

以上的布局文件很简单,不再做介绍。接着进入正文

Activity

public class MainActivity extends Activity {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
Map<String, Object> map = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.mylist);
ListView lv = (ListView)findViewById(R.id.listview);
SimpleAdapter adapter = new SimpleAdapter(this, getData(),
R.layout.simple_item, new String[] { "img", "title", "info" },
new int[] { R.id.img, R.id.title, R.id.info });

adapter.setViewBinder(new MyViewBinder());
lv.setAdapter(adapter);
}
private List<Map<String, Object>> getData() {
Cursor cursor = null;
String[] proj = {MediaStore.Images.Media.DATA};
cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj, null, null, null);
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
Map<String, Object> map = null;
int i = 0;
while(cursor.moveToNext()){
i++;
String strPath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
FileInputStream is = null;
try {
is = new FileInputStream(strPath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BitmapFactory.Options op = new BitmapFactory.Options();
op.inTempStorage = new byte[100 * 1024];
op.inPreferredConfig = Bitmap.Config.RGB_565;
op.inPurgeable = true;
op.inSampleSize = 4;
op.inInputShareable = true;
Bitmap bmp =BitmapFactory.decodeStream(is,null, op);
//Bitmap bmp = BitmapFactory.decodeFile(strPath,op);
map = new HashMap<String, Object>();
map.put("img", bmp);
map.put("title", "myTitle"+i);
map.put("info", " myContent" + i);
list.add(map);
}
return list;
}
}


讲一些适配器的用法SimpleAdapter
要构造一个SimpleAdapter,需要以下的参数:

1.Context context:上下文,这个是每个组件都需要的,它指明了SimpleAdapter关联的View的运行环境,也就是我们当前的Activity。
2.List<? extends Map<String, ?>> data:这是一个由Map组成的List,在该List中的每个条目对应ListView的一行,每一个Map中包含的就是所有在from参数中指定的key。
3.int resource:定义列表项的布局文件的资源ID,该资源文件至少应该包含在to参数中定义的ID。
4.String[] from:将被添加到Map映射上的key。
5.int[] to:将绑定数据的视图的ID跟from参数对应,在上例中ID对应img,title和info,一个ImageView和两个TextView

注意:在使用SimpleAdapter时,如果图片资源是在drawable文件夹里可以直接这样用
Map<String, Object> map = new HashMap<String, Object>();
map.put("img", R.drawable.img);
map.put("title", "大黄");
map.put("info", "是小狗");
list.add(map);

但是如果是网络图片或者是本文章的图片在手机的任意位置就需要用到ViewBinder,所以原文中加了一句 adapter.setViewBinder(new MyViewBinder());

MyViewBinder实现了ViewBinder接口

public class MyViewBinder implements SimpleAdapter.ViewBinder {

@Override
public boolean setViewValue(View view, Object data, String textRepresentation) {
// TODO Auto-generated method stub
if((view instanceof ImageView)&(data instanceof Bitmap))
{
ImageView iv = (ImageView)view;
Bitmap bmp = (Bitmap)data;
iv.setImageBitmap(bmp);
return true;
}
return false;
}

}


该类用于 SimpleAdapter 的外部客户将适配器的值绑定到视图. 你可以使用此类将 SimpleAdapter 不支持的值绑定到视图,或者改变 SimpleAdapter 支持的视图的绑定方式.

public abstract boolean setViewValue (View view, Object data, String textRepresentation)

绑定指定的数据到指定的视图. 当使用 ViewBinder 绑定了数据时,必须返回真.如果该方法返回假, SimpleAdapter 会用自己的方式去绑定数据.

view 要绑定数据的视图

data 绑定用的数据

textRepresentation 代表所提供的数据的安全字符串: 或者是 data.toString(),或者是空串,不能为空.

以上的问题还算简单,但是接下来的问题折腾了我很久

就是利用数据库查询图片的时候经常会OutOfMemory,后来找了一篇博客讲的不错下面的讲解看不懂的可以详细参考http://blog.csdn.net/shuaihj/article/details/8808409。

解决方案

private ImageView preview;

//1.加载位图

inputStream is = new FileInputStream(path)

//2.为位图设置100K的缓存

BitmapFactory.Options opts=new BitmapFactory.Options();

opts.inTempStorage = new byte[100 * 1024];

//3.设置位图颜色显示优化方式

//ALPHA_8:每个像素占用1byte内存(8位)

//ARGB_4444:每个像素占用2byte内存(16位)

//ARGB_8888:每个像素占用4byte内存(32位)

//RGB_565:每个像素占用2byte内存(16位)

//Android默认的颜色模式为ARGB_8888,这个颜色模式色彩最细腻,显示质量最高。但同样的,占用的内存//也最大。也就意味着一个像素点占用4个字节的内存。我们来做一个简单的计算题:3200*2400*4 bytes //=30M。如此惊人的数字!哪怕生命周期超不过10s,Android也不会答应的。

opts.inPreferredConfig = Bitmap.Config.RGB_565;

//4.设置图片可以被回收,创建Bitmap用于存储Pixel的内存空间在系统内存不足时可以被回收

opts.inPurgeable = true;

//5.设置位图缩放比例

//width,hight设为原来的四分一(该参数请使用2的整数倍),这也减小了位图占用的内存大小;例如,一张//分辨率为2048*1536px的图像使用inSampleSize值为4的设置来解码,产生的Bitmap大小约为//512*384px。相较于完整图片占用12M的内存,这种方式只需0.75M内存(假设Bitmap配置为//ARGB_8888)。

opts.inSampleSize = 4;

//6.设置解码位图的尺寸信息

opts.inInputShareable = true;

//7.解码位图

Bitmap btp =BitmapFactory.decodeStream(is,null, opts);

源文件程序下载http://download.csdn.net/detail/shouwangyaoyuan/9317311
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: