废话不多说,上代码
首先是MainActivity
package com.example.tsm.xmldemo;
import android.app.Dialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button search,button_openfile;
private ListView list;
private ArrayList persons;
//private SimpleAdapter mAdapter;
private int [] tImg = new int[]{R.mipmap.ic_launcher_round,R.mipmap.ic_launcher_round,R.mipmap.ic_launcher_round,R.mipmap.ic_launcher_round,R.mipmap.ic_launcher_round};
private String [] name = new String[10];
private String [] phoneNumber = new String[10];
private String [] temp = new String[3];
private String filepath = null;
static private int openfileDialogId = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setView();
}
private void setView(){
search = (Button) findViewById(R.id.search);
list = (ListView) findViewById(R.id.list);
button_openfile = (Button) findViewById(R.id.button_openfile);
search.setOnClickListener(this);
button_openfile.setOnClickListener(this);
}
private ArrayList readxmlForSAX() throws Exception {
//获取文件资源建立输入流对象
InputStream is = new FileInputStream(filepath);
//①创建XML解析处理器
SaxHelper ss = new SaxHelper();
//②得到SAX解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//③创建SAX解析器
SAXParser parser = factory.newSAXParser();
//④将xml解析处理器分配给解析器,对文档进行解析,将事件发送给处理器
parser.parse(is, ss);
is.close();
return ss.getPersons();
}
@Override
protected Dialog onCreateDialog(int id) {
if(id==openfileDialogId){
Map images = new HashMap();
// 下面几句设置各文件类型的图标, 需要你先把图标添加到资源文件夹
images.put(OpenFileDialog.sRoot, R.drawable.filedialog_root); // 根目录图标
images.put(OpenFileDialog.sParent, R.drawable.filedialog_folder_up); //返回上一层的图标
images.put(OpenFileDialog.sFolder, R.drawable.filedialog_folder); //文件夹图标
images.put("xml",R.drawable.filedialog_file); //文件图标
images.put("wav", R.drawable.filedialog_wavfile); //wav文件图标
images.put(OpenFileDialog.sEmpty, R.drawable.filedialog_root);
Dialog dialog = OpenFileDialog.createDialog(id, this, "打开文件", new CallbackBundle() {
@Override
public void callback(Bundle bundle) {
filepath = bundle.getString("path");
Toast.makeText(getApplicationContext(),"选择成功!",Toast.LENGTH_LONG).show();
//setTitle(filepath); // 把文件路径显示在标题上
}
},
".wav;.xml;",
images);
return dialog;
}
return null;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.search:
// String path=getApplicationContext().getFilesDir().getAbsolutePath();
// Toast.makeText(getApplicationContext(),filepath+"&&"+path,Toast.LENGTH_LONG).show();
// //Log.i("XXXXQQQQ",filepath+"&&"+path);
//Log.i("xxx","执行了1");
try {
persons = readxmlForSAX();
//Log.i("xxx","执行了2");
} catch (Exception e) {
e.printStackTrace();
}
//mAdapter = new ArrayAdapter(MainActivity.this, R.layout.list_item, persons);
List
通讯录对象属性存储类
person
package com.example.tsm.xmldemo;
/**
* Created by TSM on 2017/4/29.
*/
public class Person {
private int id;
private String name;
private String phoneNumber;
public Person(int id, String name, String phoneNumber) {
this.id = id;
this.name = name;
this.phoneNumber = phoneNumber;
}
public Person() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Override
public String toString() {
return this.name + "," + this.phoneNumber;
}
}
使用SAX方式解析XML文档
SaxHelper
package com.example.tsm.xmldemo;
import android.util.Log;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
/**
* Created by TSM on 2017/4/29.
*/
public class SaxHelper extends DefaultHandler {
private Person person;
private ArrayList persons;
//当前解析的元素标签
private String tagName = null;
/**
* 当读取到文档开始标志是触发,通常在这里完成一些初始化操作
*/
@Override
public void startDocument() throws SAXException {
this.persons = new ArrayList();
//Log.i("SAX", "读取到文档头,开始解析xml");
}
/**
* 读到一个开始标签时调用,第二个参数为标签名,最后一个参数为属性数组
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equals("person")) {
person = new Person();
person.setId(Integer.parseInt(attributes.getValue("id")));
//Log.i("SAX", "开始处理person元素~");
}
this.tagName = localName;
}
/**
* 读到到内容,第一个参数为字符串内容,后面依次为起始位置与长度
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
//判断当前标签是否有效
if (this.tagName != null) {
String data = new String(ch, start, length);
//读取标签中的内容
if (this.tagName.equals("name")) {
this.person.setName(data);
//Log.i("SAX", "处理name元素内容");
} else if (this.tagName.equals("phoneNumber")) {
this.person.setPhoneNumber(data);
//Log.i("SAX", "处理age元素内容");
}
}
}
/**
* 处理元素结束时触发,这里将对象添加到结合中
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (localName.equals("person")) {
this.persons.add(person);
person = null;
//Log.i("SAX", "处理person元素结束~");
}
this.tagName = null;
}
/**
* 读取到文档结尾时触发,
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
//Log.i("SAX", "读取到文档尾,xml解析结束");
}
//获取persons集合
public ArrayList getPersons() {
return persons;
}
}
现在开始写打开弹出框选择文件的代码了
OpenFileDialog
package com.example.tsm.xmldemo;
/**
* Created by TSM on 2017/4/29.
*/
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class OpenFileDialog {
public static String tag = "OpenFileDialog";
static final public String sRoot = "/";
static final public String sParent = "..";
static final public String sFolder = ".";
static final public String sEmpty = "";
static final private String sOnErrorMsg = "No rights to access!";
// 参数说明
// context:上下文
// dialogid:对话框ID
// title:对话框标题
// callback:一个传递Bundle参数的回调接口
// suffix:需要选择的文件后缀,比如需要选择wav、mp3文件的时候设置为".wav;.mp3;",注意最后需要一个分号(;)
// images:用来根据后缀显示的图标资源ID。
// 根目录图标的索引为sRoot;
// 父目录的索引为sParent;
// 文件夹的索引为sFolder;
// 默认图标的索引为sEmpty;
// 其他的直接根据后缀进行索引,比如.wav文件图标的索引为"wav"
public static Dialog createDialog(int id, Context context, String title, CallbackBundle callback, String suffix, Map images){
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setView(new FileSelectView(context, id, callback, suffix, images));
Dialog dialog = builder.create();
//dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setTitle(title);
return dialog;
}
static class FileSelectView extends ListView implements OnItemClickListener{
private CallbackBundle callback = null;
private String path = sRoot;
private List> list = null;
private int dialogid = 0;
private String suffix = null;
private Map imagemap = null;
public FileSelectView(Context context, int dialogid, CallbackBundle callback, String suffix, Map images) {
super(context);
this.imagemap = images;
this.suffix = suffix==null?"":suffix.toLowerCase();
this.callback = callback;
this.dialogid = dialogid;
this.setOnItemClickListener(this);
refreshFileList();
}
private String getSuffix(String filename){
int dix = filename.lastIndexOf('.');
if(dix<0){
return "";
}
else{
return filename.substring(dix+1);
}
}
private int getImageId(String s){
if(imagemap == null){
return 0;
}
else if(imagemap.containsKey(s)){
return imagemap.get(s);
}
else if(imagemap.containsKey(sEmpty)){
return imagemap.get(sEmpty);
}
else {
return 0;
}
}
private int refreshFileList()
{
// 刷新文件列表
File[] files = null;
try{
files = new File(path).listFiles();
}
catch(Exception e){
files = null;
}
if(files==null){
// 访问出错
Toast.makeText(getContext(), sOnErrorMsg,Toast.LENGTH_SHORT).show();
return -1;
}
if(list != null){
list.clear();
}
else{
list = new ArrayList>(files.length);
}
// 用来先保存文件夹和文件夹的两个列表
ArrayList> lfolders = new ArrayList>();
ArrayList> lfiles = new ArrayList>();
if(!this.path.equals(sRoot)){
// 添加根目录 和 上一层目录
Map map = new HashMap();
map.put("name", sRoot);
map.put("path", sRoot);
map.put("img", getImageId(sRoot));
list.add(map);
map = new HashMap();
map.put("name", sParent);
map.put("path", path);
map.put("img", getImageId(sParent));
list.add(map);
}
for(File file: files)
{
if(file.isDirectory() && file.listFiles()!=null){
// 添加文件夹
Map map = new HashMap();
map.put("name", file.getName());
map.put("path", file.getPath());
map.put("img", getImageId(sFolder));
lfolders.add(map);
}
else if(file.isFile()){
// 添加文件
String sf = getSuffix(file.getName()).toLowerCase();
if(suffix == null || suffix.length()==0 || (sf.length()>0 && suffix.indexOf("."+sf+";")>=0)){
Map map = new HashMap();
map.put("name", file.getName());
map.put("path", file.getPath());
map.put("img", getImageId(sf));
lfiles.add(map);
}
}
}
list.addAll(lfolders); // 先添加文件夹,确保文件夹显示在上面
list.addAll(lfiles); //再添加文件
SimpleAdapter adapter = new SimpleAdapter(getContext(), list, R.layout.filedialogitem, new String[]{"img", "name", "path"}, new int[]{R.id.filedialogitem_img, R.id.filedialogitem_name, R.id.filedialogitem_path});
this.setAdapter(adapter);
return files.length;
}
@Override
public void onItemClick(AdapterView> parent, View v, int position, long id) {
// 条目选择
String pt = (String) list.get(position).get("path");
String fn = (String) list.get(position).get("name");
if(fn.equals(sRoot) || fn.equals(sParent)){
// 如果是更目录或者上一层
File fl = new File(pt);
String ppt = fl.getParent();
if(ppt != null){
// 返回上一层
path = ppt;
}
else{
// 返回更目录
path = sRoot;
}
}
else{
File fl = new File(pt);
if(fl.isFile()){
// 如果是文件
((Activity)getContext()).dismissDialog(this.dialogid); // 让文件夹对话框消失
// 设置回调的返回值
Bundle bundle = new Bundle();
bundle.putString("path", pt);
bundle.putString("name", fn);
// 调用事先设置的回调函数
this.callback.callback(bundle);
return;
}
else if(fl.isDirectory()){
// 如果是文件夹
// 那么进入选中的文件夹
path = pt;
}
}
this.refreshFileList();
}
}
}
接口:CallbackBundle
package com.example.tsm.xmldemo;
import android.os.Bundle;
/**
* Created by TSM on 2017/4/29.
*/
public interface CallbackBundle {
abstract void callback(Bundle bundle);
}
好了,处理的工作写完啦,现在开始写界面代码了
activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_margin="10dp">
<Button
android:id="@+id/search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/search"/>
<Button
android:id="@+id/button_openfile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/diag"/>
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
ListView>
LinearLayout>
filedialogitem.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/vw1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#000000"
android:orientation="horizontal"
android:padding="4dp" >
<ImageView
android:id="@+id/filedialogitem_img"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="4dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/filedialogitem_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/filedialogitem_path"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:textColor="#FFFFFF"
android:textSize="14sp" />
LinearLayout>
LinearLayout>
list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="5dp"
>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@mipmap/ic_launcher_round" />
<TextView
android:id="@+id/name"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:textColor="@color/colorfont"
android:text="姓名"/>
<TextView
android:id="@+id/phoneNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="@color/colorfont"
android:text="17673116337"/>
LinearLayout>
LinearLayout>
用于解析的xml文件,把文件置于Android系统的mnt/sdcard文件夹下吧
person.xml
<persons>
<person id = "1">
<name>沙瑞金name>
<phoneNumber>17673156987phoneNumber>
person>
<person id = "2">
<name>赵东来name>
<phoneNumber>13008965489phoneNumber>
person>
<person id = "3">
<name>刘大name>
<phoneNumber>15276321254phoneNumber>
person>
<person id = "4">
<name>侯亮平name>
<phoneNumber>18963985236phoneNumber>
person>
<person id = "5">
<name>高育良name>
<phoneNumber>17584563215phoneNumber>
person>
persons>