我是靠谱客的博主 痴情纸鹤,这篇文章主要介绍【Android】读取sdcard卡上的所有图片并且显示,读取的过程有进度条显示,现在分享给大家,希望可以做个参考。

虽然下面的app还没有做到快图浏览、ES文件浏览器的水平,遇到大sdcard还是会存在读取过久、内存溢出等问题,但是基本思想是这样的。

如下图,在sdcard卡上有4张图片,


打开app,则会吧sd卡上的所有图片读取,并显示出来,读取的过程有进度条显示。


制作过程如下:

1、首先,resvaluesstrings.xml对字符设置如下,没有什么特别的。

复制代码
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">读取sdcard下的所有图片</string> <string name="action_settings">Settings</string> <string name="imageView_description">大图</string> </resources>
2、之后,修改reslayoutactivity_main.xml形成布局,这里采用布局与《【Android】画廊式的图片浏览器,使用HorizontalScrollView取代Gallery,OnClickListener的参数传递》( 点击打开链接)是一模一样的,只是这里,HorizontalScrollView旗下的LinearLayout改为用Java代码生成,故对HorizontalScrollView赋予id。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/imageView1" android:layout_width="match_parent" android:layout_height="200dp" android:contentDescription="@string/imageView_description" android:paddingTop="10dp" /> <HorizontalScrollView android:id="@+id/horizontalScrollView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:scrollbars="horizontal" > </HorizontalScrollView> </LinearLayout>

3、然后,与《【Android】读取sdcard上的图片》(点击打开链接)一样,在AndroidManifest.xml插入<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />与<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />要求对sdcard读取与写入的权限,这个文件修改之后如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.asyncread" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 要求向SDCard读取数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 要求向SDCard写入数据权限 --> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.asyncread.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
4、最后,才是整个程序的关键,对MainActivity.java的编写。这里首先插入了两个工具类,一个在《【Java】读取其下所有文件夹与文件的路径》( 点击打开链接)中讲过,用于遍历sdcard上面的文件的,当然,遍历的时候剔除sdcard上Android这个系统文件夹,不剔除的话会把系统的图标等遍历出来。之后是一个图片缩放类,不对读取到的图片进行缩放,会在app运行时,出现内存溢出的错误。

程序一开始,在onCreate方法,在app头部生成一个进度条,之后调用异步类AsyncTask对sdcard卡文件的读取,与《【Android】画廊式的图片浏览器,使用HorizontalScrollView取代Gallery,OnClickListener的参数传递》(点击打开链接)中的方法一样,把图片资源一张张加载出来。只是作用对象从app的图片资源,变成从sdcard读取出来的图片。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package com.example.asyncread; import java.io.File; import java.util.ArrayList; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.Window; import android.widget.HorizontalScrollView; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; public class MainActivity extends Activity { // 安卓组件 private HorizontalScrollView horizontalScrollView1; private ImageView imageView1; // 用于存放sdcard卡上的所有图片路径 public static ArrayList<String> dirAllStrArr = new ArrayList<String>(); // 用于遍历sdcard卡上所有文件的类 public static void DirAll(File dirFile) throws Exception { if (dirFile.exists()) { File files[] = dirFile.listFiles(); for (File file : files) { if (file.isDirectory()) { String fileName = file.getName(); // 除sdcard上Android这个文件夹以外。 if (!fileName.endsWith("Android")) { // 如果遇到文件夹则递归调用。 DirAll(file); } } else { // 如果是图片文件压入数组 String fileName = file.getName(); if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") || fileName.endsWith(".bmp") || fileName.endsWith(".gif") || fileName.endsWith(".png")) { // 如果遇到文件则放入数组 if (dirFile.getPath().endsWith(File.separator)) { dirAllStrArr .add(dirFile.getPath() + file.getName()); } else { dirAllStrArr.add(dirFile.getPath() + File.separator + file.getName()); } } } } } } // 图片加载的类 public static BitmapFactory.Options getHeapOpts(File file) { BitmapFactory.Options opts = new BitmapFactory.Options(); // 数字越大读出的图片占用的heap必须越小,不然总是溢出 if (file.length() < 20480) { // 0-20k opts.inSampleSize = 1;// 这里意为缩放的大小 } else if (file.length() < 51200) { // 20-50k opts.inSampleSize = 2; } else if (file.length() < 307200) { // 50-300k opts.inSampleSize = 4; } else if (file.length() < 819200) { // 300-800k opts.inSampleSize = 6; } else if (file.length() < 1048576) { // 800-1024k opts.inSampleSize = 8; } else { opts.inSampleSize = 10; } return opts; } class MyTask extends AsyncTask<Void, Integer, LinearLayout> { @Override // 任务开始前做什么 protected void onPreExecute() { setProgressBarVisibility(true);// 显示进度条 super.onPreExecute(); } @Override protected LinearLayout doInBackground(Void... arg0) { // 生成一个水平线性布局 LinearLayout linearLayout1 = new LinearLayout(MainActivity.this); LayoutParams layoutParams = new LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); linearLayout1.setOrientation(LinearLayout.HORIZONTAL); linearLayout1.setLayoutParams(layoutParams);// 应用到新生成的线性布局 /* 遍历sdcard旗下的所有文件夹开始 */ String sdpath = Environment.getExternalStorageDirectory() .getAbsolutePath();// 获取sdcard的根路径 File dirFile = new File(sdpath); try { DirAll(dirFile); } catch (Exception e) { e.printStackTrace(); } /* 遍历sdcard旗下的所有文件夹结束 */ // 得到sdcard旗下的所有图片路径之后,再对这个数组进行遍历 for (int i = 0; i < dirAllStrArr.size(); i++) { String filePath = dirAllStrArr.get(i); File file = new File(filePath); Bitmap bm = BitmapFactory.decodeFile(filePath, getHeapOpts(file)); LinearLayout linearLayout2 = new LinearLayout(MainActivity.this); // 设置新生成线性布局的参数,宽度为100,高度为匹配父组件,也就是水平滚动视图的高度 LayoutParams layoutParams1 = new LayoutParams(100, ViewGroup.LayoutParams.MATCH_PARENT); layoutParams1.gravity = Gravity.CENTER_HORIZONTAL;// 设置线性布局内的组件水平居中 linearLayout2.setOrientation(LinearLayout.VERTICAL);// 设置新生成的线性布局android:orientation="vertical" linearLayout2.setLayoutParams(layoutParams1);// 应用到新生成的线性布局 ImageView imageView2 = new ImageView(MainActivity.this); imageView2.setId(i + 20000);// 这里由于id不能为字符的缘故,所有对图片的id分别设为20000,20001,20002,...便于下面的图片点击监听器所控制 imageView2.setImageBitmap(bm);// 将数组中的第i张图片放到图片视图 imageView2.setAdjustViewBounds(true);// 自动缩放为宽高比 imageView2.setMaxHeight(80);// 图片的高度为80dp imageView2.setPadding(10, 10, 10, 10); imageView2.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { String filePath = dirAllStrArr.get(view.getId() - 20000); File file = new File(filePath); Bitmap bm = BitmapFactory.decodeFile(filePath, getHeapOpts(file)); imageView1.setImageBitmap(bm); // 把点击的图片id取出之后,减20000就是要显示的图片在图片数组的位置了。 } }); // 将图片视图加载到新生成的线性布局之中 linearLayout2.addView(imageView2); // 新生成一个标签文本 TextView textView = new TextView(MainActivity.this); textView.setText(filePath); textView.setTextSize(15); // 标签文本在水平位置居中 textView.setGravity(Gravity.CENTER); // 添加到新生成的线性布局之后 linearLayout2.addView(textView); linearLayout1.addView(linearLayout2); publishProgress(i);// 调用onProgressUpdate方法 } return linearLayout1; } @Override protected void onProgressUpdate(Integer... values) { setProgress(values[0] * 2500);// 更新进度条 super.onProgressUpdate(values); } // 任务放完之后 @Override protected void onPostExecute(LinearLayout result) { setProgressBarVisibility(false); horizontalScrollView1.addView(result);// 把doInBackground()最终搞出来的水平线性布局放到横向滚动布局中 super.onPostExecute(result); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_PROGRESS);// 在头部生成一个进度条,必须在setContentView(R.layout.activity_main);这条语句之前 setContentView(R.layout.activity_main); // 获取各种组件 horizontalScrollView1 = (HorizontalScrollView) findViewById(R.id.horizontalScrollView1); imageView1 = (ImageView) findViewById(R.id.imageView1); new MyTask().execute();// 开始MyTask任务 } }


最后

以上就是痴情纸鹤最近收集整理的关于【Android】读取sdcard卡上的所有图片并且显示,读取的过程有进度条显示的全部内容,更多相关【Android】读取sdcard卡上内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部