【Android】读取sdcard卡上的所有图片并且显示,读取的过程有进度条显示

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

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

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

制作过程如下:

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

<?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、之后,修改res\layout\activity_main.xml形成布局,这里采用布局与《【Android】画廊式的图片浏览器,使用HorizontalScrollView取代Gallery,OnClickListener的参数传递》(点击打开链接)是一模一样的,只是这里,HorizontalScrollView旗下的LinearLayout改为用Java代码生成,故对HorizontalScrollView赋予id。

<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读取与写入的权限,这个文件修改之后如下:

<?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读取出来的图片。

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任务
	}

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-14 23:24:58

【Android】读取sdcard卡上的所有图片并且显示,读取的过程有进度条显示的相关文章

【Android】读取sdcard卡上的全部图片而且显示,读取的过程有进度条显示

尽管以下的app还没有做到快图浏览.ES文件浏览器的水平,遇到大sdcard还是会存在读取过久.内存溢出等问题,可是基本思想是这种. 例如以下图.在sdcard卡上有4张图片, 打开app,则会吧sd卡上的全部图片读取,并显示出来.读取的过程有进度条显示. 制作步骤例如以下: 1.首先,res\values\strings.xml对字符设置例如以下,没有什么特别的. <? xml version="1.0" encoding="utf-8"?> <

android 操作SD卡上的文件

(1)说明:操作SD卡上的文件需要加入以下权限 在SD卡上创建和删除文件权限 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 在SD卡上写入数据的权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 在sd卡上的文件操作和我上一篇文

Struts2 文件上传 进度条显示

参考成功博客:http://blog.sina.com.cn/s/blog_bca9d7e80101bkko.html 待测试博客:http://blog.csdn.net/z69183787/article/details/52536255 Struts2 文件上传 进度条显示

Ajax上传文件进度条显示

要实现进度条的显示,就要知道两个参数,上传的大小和总文件的大小 html5提供了一个上传过程事件,在上传过程中不断触发,然后用已上传的大 小/总大小,计算上传的百分比,然后用这个百分比控制div框的显示,就可以 实现上传的进度条效果 前端页面 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Ajax上传文件进度条显示

Extjs 使用fileupload插件上传文件 带进度条显示

一.首先我们看看官方给出的插件的解释: 一个文件上传表单项具有自定义的样式,并且可以控制按钮的文本和 像文本表单的空文本类似的其他特性. 它使用一个隐藏的文件输入元素,并在用户选择文件后 在form提交的同时执行实际的文件上传. 因为没有安全的跨浏览器以编程的方式对file表单项设值的方式, 所以标准表单项的 setValue 方法是无效的. getvalue方法的返回值取决于使用何种浏览器; 一些仅仅返回文件名, 一些返回一个完整的文件路径, 一些则返回文件的虚拟路径. 二.在我看来这个插件就

android保存USIM卡上的联系人时,提示“不能保存电话号码为空的联系人”的问题

1.USIM卡上有一个联系人,有电话号码和名字 2.修改该联系人,将name删除 3.将电话字段中的"手机"替换为"其他" 4.保存时会提示"不能保存电话号码为空的联系人" 這是USIM卡的設計:Name 和 Number不能同時為空. 當把 Number 的 Type 改成 other 後,它會被改設到 "Additional number" 的欄位,而導致 Number 變為空. 所以無法存成功,這是正常的行為. 这个问题

用进度条显示从网络上下载文件进度

/* * 根据上课的案例,利用进度条控件程序进行下载操作.... */public class Aty_HttpDownLoad_ProgressBar extends Activity { private ProgressBar pB; private TextView tv_progress; private static final int DOWNLOADING=1; private static final int DOWNLOAD_SUCCESS=2; private double

Android学习笔记--使用HttpURLConnection实现网络下载效果,附带进度条显示

下面我就直接上代码了,因为代码中我已经写了非常详细的注释 1 package com.wuxianedu.httpdemo; 2 3 import android.app.ProgressDialog; 4 import android.content.Intent; 5 import android.net.Uri; 6 import android.os.AsyncTask; 7 import android.os.Handler; 8 import android.os.Message;

Android——音乐播放器完善——进度条显示当前播放进度,加可拖动进度条(未待解决完问题)

效果: 问题:可拖动进度条随进度条移动时,会致使音乐卡顿(待解决) xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:l