一、简单介绍
本人最近才接触android,算是典型的菜鸟吧。自学一段时间后制作了一个很简陋的图片浏览器。借此博客分享大赛,和大家共同交流促进。
本程序使用到的组件有:ListView,TextView,ImageView和Menu,对返回键,菜单选项和ListActivity进行监听,使用了BitmapFactory显示图片,并使用了Dialog风格的Activity。
二、实现细节
接下来就具体介绍一下各个代码的细节。
(1)FileListActivity.java
运行效果如下图:
具体代码:
- /**
- * 使用ListActivity来显示SD卡的文件
- * 用户可在此选择要显示的图片
- */
- public class FileListActivity extends ListActivity {
- private static final int ID_ABOUT=1;
- private static final int ID_EXIT=2;
- private File rootFile = null;
- private File currentFile = null;
- private ArrayList<HashMap<String, String>> fileList = null;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //获取SD卡的路径
- rootFile = Environment.getExternalStorageDirectory();
- currentFile = rootFile;
- //显示文件列表
- showDir(rootFile);
- }
- //根据传入的File参数显示该File所在的文件
- public void showDir(File pathFile) {
- //ArrayList保存文件目录下每个文件条目,HashMap的键保存文件名,值保存文件路径
- fileList = new ArrayList<HashMap<String, String>>();
- if (pathFile != null && pathFile.exists()) {
- File[] files = pathFile.listFiles();
- //将父目录作为文件条目,用户可选择返回上层目录
- if (pathFile.getParentFile() != rootFile.getParentFile()) {
- HashMap<String, String> map = new HashMap<String, String>();
- map.put("name", pathFile.getParentFile().getName());
- map.put("path", pathFile.getParent());
- fileList.add(map);
- }
- //遍历当前目录下的文件和文件夹(忽略点文件),存进ArrayList
- for (File f : files) {
- if(!f.getName().startsWith(".")){
- HashMap<String, String> map1 = new HashMap<String, String>();
- map1.put("name", f.getName());
- map1.put("path", f.getPath());
- fileList.add(map1);
- }
- }
- }
- //使用SimpleAdapter作为ListActivity的适配器
- SimpleAdapter sa = new SimpleAdapter(
- //当前类
- this,
- //要显示的资源
- fileList,
- //ListActivity的布局文件
- R.layout.list,
- //要显示的每一列的名称(这里只显示一列)
- new String[] { "name" },
- //每一列对应的布局文件
- new int[] { R.id.file_name });
- //为ListActivity设置适配器
- setListAdapter(sa);
- }
- //创建菜单选项
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(0, ID_ABOUT, 1, R.string.about);
- menu.add(0, ID_EXIT, 2, R.string.exit);
- return super.onCreateOptionsMenu(menu);
- }
- //监听用户对菜单项目的选择,根据ItemID执行相应方法
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if(item.getItemId()==ID_ABOUT)
- showAbout();
- if(item.getItemId()==ID_EXIT)
- finish();
- return super.onOptionsItemSelected(item);
- }
- //监听返回键,当用户点击返回键时,返回上层目录
- @Override
- public void onBackPressed() {
- if(currentFile.getPath().equals(rootFile.getPath()))
- super.onBackPressed();
- else {
- currentFile=currentFile.getParentFile();
- showDir(currentFile);
- }
- }
- //监听用户选择的文件,若选择的是图片,则显示,若是文件夹,则进入下一层
- @Override
- protected void onListItemClick(ListView l, View v, int position, long id) {
- //获取用户选择的路径
- String currentPath = fileList.get(position).get("path");
- currentFile = new File(currentPath);
- //如果该路径是文件夹,则进入下一层
- if (currentFile.isDirectory()) {
- showDir(currentFile);
- } else {
- //如果是图片,则显示(本例只支持jpg,可以自行添加其他格式)
- if (currentPath.endsWith(".jpg")) {
- //通过Intent传递图片路径
- Intent intent = new Intent();
- intent.putExtra("picPath", currentPath);
- intent.setClass(this, ImageViewerActivity.class);
- this.startActivity(intent);
- }
- }
- }
- //显示“关于”信息
- private void showAbout() {
- Intent intent=new Intent();
- intent.setClass(this, AboutMsg.class);
- this.startActivity(intent);
- }
- }
/**
* 使用ListActivity来显示SD卡的文件
* 用户可在此选择要显示的图片
*/
public class FileListActivity extends ListActivity {
private static final int ID_ABOUT=1;
private static final int ID_EXIT=2;
private File rootFile = null;
private File currentFile = null;
private ArrayList<HashMap<String, String>> fileList = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//获取SD卡的路径
rootFile = Environment.getExternalStorageDirectory();
currentFile = rootFile;
//显示文件列表
showDir(rootFile);
}
//根据传入的File参数显示该File所在的文件
public void showDir(File pathFile) {
//ArrayList保存文件目录下每个文件条目,HashMap的键保存文件名,值保存文件路径
fileList = new ArrayList<HashMap<String, String>>();
if (pathFile != null && pathFile.exists()) {
File[] files = pathFile.listFiles();
//将父目录作为文件条目,用户可选择返回上层目录
if (pathFile.getParentFile() != rootFile.getParentFile()) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", pathFile.getParentFile().getName());
map.put("path", pathFile.getParent());
fileList.add(map);
}
//遍历当前目录下的文件和文件夹(忽略点文件),存进ArrayList
for (File f : files) {
if(!f.getName().startsWith(".")){
HashMap<String, String> map1 = new HashMap<String, String>();
map1.put("name", f.getName());
map1.put("path", f.getPath());
fileList.add(map1);
}
}
}
//使用SimpleAdapter作为ListActivity的适配器
SimpleAdapter sa = new SimpleAdapter(
//当前类
this,
//要显示的资源
fileList,
//ListActivity的布局文件
R.layout.list,
//要显示的每一列的名称(这里只显示一列)
new String[] { "name" },
//每一列对应的布局文件
new int[] { R.id.file_name });
//为ListActivity设置适配器
setListAdapter(sa);
}
//创建菜单选项
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, ID_ABOUT, 1, R.string.about);
menu.add(0, ID_EXIT, 2, R.string.exit);
return super.onCreateOptionsMenu(menu);
}
//监听用户对菜单项目的选择,根据ItemID执行相应方法
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==ID_ABOUT)
showAbout();
if(item.getItemId()==ID_EXIT)
finish();
return super.onOptionsItemSelected(item);
}
//监听返回键,当用户点击返回键时,返回上层目录
@Override
public void onBackPressed() {
if(currentFile.getPath().equals(rootFile.getPath()))
super.onBackPressed();
else {
currentFile=currentFile.getParentFile();
showDir(currentFile);
}
}
//监听用户选择的文件,若选择的是图片,则显示,若是文件夹,则进入下一层
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
//获取用户选择的路径
String currentPath = fileList.get(position).get("path");
currentFile = new File(currentPath);
//如果该路径是文件夹,则进入下一层
if (currentFile.isDirectory()) {
showDir(currentFile);
} else {
//如果是图片,则显示(本例只支持jpg,可以自行添加其他格式)
if (currentPath.endsWith(".jpg")) {
//通过Intent传递图片路径
Intent intent = new Intent();
intent.putExtra("picPath", currentPath);
intent.setClass(this, ImageViewerActivity.class);
this.startActivity(intent);
}
}
}
//显示“关于”信息
private void showAbout() {
Intent intent=new Intent();
intent.setClass(this, AboutMsg.class);
this.startActivity(intent);
}
}
这里简单使用了java的文件类File和遍历进行文件操作。
需要注意的是SD卡的路径我用Environment.getExternalStorageDirectory()来获取,而不是写死为/SDcard之类,因为SD卡的路径在不同的手机中会有差异,因此不建议写死。
此外考虑到有些用户习惯用返回键来返回到上层目录,因此使用onBackPressed()对返回键进行监听,若当前不为SD卡的根目录,则返回上层目录,否则退出。
其中ListActivity使用到的两个布局文件listmain.xml和list.xml比较简单,具体代码如下:
listmain.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <ListView
- android:id="@id/android:list"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:scrollbars="vertical">
- </ListView>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@id/android:list"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:scrollbars="vertical">
</ListView>
</LinearLayout>
list.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="35px">
- <TextView
- android:id="@+id/file_name"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:text="25px"
- android:gravity="center"
- ></TextView>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="35px">
<TextView
android:id="@+id/file_name"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="25px"
android:gravity="center"
></TextView>
</LinearLayout>
其中listmain.xml是整个ListActivity的布局文件,list.xml是具体ListView的布局文件。
(2)ImageViewerActivity.java
运行效果如下图:
具体代码:
- /**
- * 通过Intent获取图片路径进行显示
- */
- public class ImageViewerActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //不显示该Activity标题
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.main);
- //获取Intent
- Intent receiveIntent=getIntent();
- //获取图片路径
- String picPath=receiveIntent.getStringExtra("picPath");
- ImageView iv=(ImageView)findViewById(R.id.imageView);
- //使用BitmapFactory在ImageView中显示图片
- iv.setImageBitmap(BitmapFactory.decodeFile(picPath));
- }
- }
/**
* 通过Intent获取图片路径进行显示
*/
public class ImageViewerActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//不显示该Activity标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//获取Intent
Intent receiveIntent=getIntent();
//获取图片路径
String picPath=receiveIntent.getStringExtra("picPath");
ImageView iv=(ImageView)findViewById(R.id.imageView);
//使用BitmapFactory在ImageView中显示图片
iv.setImageBitmap(BitmapFactory.decodeFile(picPath));
}
}
ImageViewerActivity通过获取从FileListActivity的Intent传来的图片路径,调用BitmapFactory.decodeFile(picPath)在ImageView中对图片进行显示。
其布局文件如下:
main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <ImageView
- android:id="@+id/imageView"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageView
android:id="@+id/imageView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
(3)AboutMsg.java
运行效果如下图:
具体代码:
- /**
- * 显示“关于”信息,内容储存在String.xml中
- */
- public class AboutMsg extends Activity{
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.about);
- }
- }
/**
* 显示“关于”信息,内容储存在String.xml中
*/
public class AboutMsg extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.about);
}
}
about.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:id="@+id/aboutTV"
- android:text="@string/about_msg"
- android:textSize="20px"
- android:padding="10px">
- </TextView>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="@+id/aboutTV"
android:text="@string/about_msg"
android:textSize="20px"
android:padding="10px">
</TextView>
</LinearLayout>
string.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="hello">Hello World, ImageViewerActivity!</string>
- <string name="app_name">ImageViewer</string>
- <string name="about">关于</string>
- <string name="exit">退出</string>
- <string name="about_msg">\n制作者:gislla\n</string>
- </resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, ImageViewerActivity!</string>
<string name="app_name">ImageViewer</string>
<string name="about">关于</string>
<string name="exit">退出</string>
<string name="about_msg">\n制作者:gislla\n</string>
</resources>
该部分用于显示程序制作者的相关信息。
另外,为了使AboutMsg显示出Dialog的效果,必须在AndroidManifest.xml中进行如下设置:
- <activity android:name=".AboutMsg"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.Dialog" >
- </activity>
<activity android:name=".AboutMsg"
android:label="@string/app_name"
android:theme="@android:style/Theme.Dialog" >
</activity>
好了,一个简陋无比的图片浏览器就到此完成了,用模拟器运行的只要在DDMS中添加图片即可。欢迎大家指教交流,谢谢大家!