Android Smart Dict - 单词导入 - 文件浏览器


搞定了数据库之后,我要想办法把单词导入进来。怎么做呢?首先找到我要导入的文件,然后导入单词。

我做了一个简单的文件浏览器,可以去sdcard里面找我需要导入的文件。我需要自己定义一种词库的文件格式和后缀名,这个不重要,目前我只需要简单的定义就好,后面再做优化。后缀名就定为“.dict",那么首先需要搞定这个文件浏览器。当然我可以用Grid View来显示文件,就像home界面的桌面一样。用户点击文件夹后进入下一级文件目录,点击文件之后判断是否是".dict"结尾的文件,如果是就加载,否则不予处理,或者显示提示信息。

这里有一个重要的问题就是,我们在读取文件的时候不能在UI主线程里边做,这样有可能会阻塞进而导致讨厌的ANR被弹出来。我们可以自定义新的线程,当然也可以使用AsyncTask来做。我这里就用Android系统的AsyncTask来做,定义一个task名叫LoadFileInfoTask,主要就是用来读取文件,取得文件信息,封装成一个定义好的FileInfo类,里面只有三个属性,文件名,路径和图片,如果是我们的词库文件就显示词库图片,依次类推。最后要注意一点,execute这个AsyncTask需要在UI线程里边来做,否则会抛异常。

具体代码如下:

  1. private class LoadFileInfoTask extends AsyncTask<String, Void, Boolean>{   
  2.     private String path;   
  3.     private FileInfo[] list;   
  4.     @Override  
  5.     protected Boolean doInBackground(String... _path) {   
  6.         path = _path[0];   
  7.         final File file = new File(path);   
  8.         if(file.isFile()) {   
  9.             // Load book file   
  10.             if (path.endsWith(BOOK_FILE_SUFFIX)) {   
  11.                 loadBook(file);   
  12.             }   
  13.             // It is not the book file   
  14.             else {   
  15.                 FileLoaderActivity.this.runOnUiThread(new Runnable() {   
  16.                     public void run() {   
  17.                         Toast.makeText(FileLoaderActivity.this, R.string.toast_not_book_file,   
  18.                                 Toast.LENGTH_SHORT).show();   
  19.                     }   
  20.                 });   
  21.             }   
  22.             return false;   
  23.         } else {   
  24.             list = getFileInfo(file);   
  25.             return true;   
  26.         }   
  27.     }   
  28.     @Override  
  29.     protected void onPostExecute(Boolean isPath) {   
  30.         if(isPath) {   
  31.             if(mFileAdapter == null) {   
  32.                 mFileAdapter = new FileAdapter(list, path);   
  33.                 mFileGrid.setAdapter(mFileAdapter);   
  34.             } else {   
  35.                 mFileAdapter.updateData(list, path);   
  36.             }   
  37.             setTitle(path);   
  38.         }   
  39.     }   
  40.     private FileInfo[] getFileInfo(File directory) {   
  41.         File[] files;   
  42.         FileInfo[] list;   
  43.         files = directory.listFiles(new FileFilter() {   
  44.             public boolean accept(File file) {   
  45.                 return file.canRead() && !file.isHidden();   
  46.             }   
  47.         });   
  48.         if(files == null) {   
  49.             return null;   
  50.         }   
  51.         list = new FileInfo[files.length];   
  52.         for (int i = 0; i < files.length; i++) {   
  53.             list[i] = new FileInfo();   
  54.             list[i].name = files[i].getName();   
  55.             String subPath = files[i].getAbsolutePath();   
  56.             // If it is a directory   
  57.             if (files[i].isDirectory()) {   
  58.                 list[i].path = Utils.formatDirectory(subPath);   
  59.                 list[i].icon = R.drawable.file_folder;   
  60.             }   
  61.             // If it is a file   
  62.             else {   
  63.                 list[i].path = subPath;   
  64.                 // Filter book files;   
  65.                 if (list[i].name.endsWith(BOOK_FILE_SUFFIX)) {   
  66.                     list[i].icon = R.drawable.file_book;   
  67.                 } else {   
  68.                     list[i].icon = R.drawable.file_unknown;   
  69.                 }   
  70.             }   
  71.         }   
  72.         return list;   
  73.     }   
  74. }  

有了这个task,我们就可以在每次点击文件夹以后运行这个task取得下一级路径的文件信息。

然后,定义一个grid view,用来显示文件信息。还有相应的Adapter,每次显示的时候更新数据。

代码如下:

  1. /**  
  2.  * Adapter for file info grid view;  
  3.  */  
  4. private class FileAdapter extends BaseAdapter {   
  5.     private FileInfo[] mList;   
  6.     private LayoutInflater inflater;   
  7.     public FileAdapter(FileInfo[] list, String path) {   
  8.         inflater = getLayoutInflater();   
  9.         updateData(list, path);   
  10.     }   
  11.     public int getCount() {   
  12.         return mList.length;   
  13.     }   
  14.     public Object getItem(int position) {   
  15.         return mList[position];   
  16.     }   
  17.     public long getItemId(int position) {   
  18.         return position;   
  19.     }   
  20.     public View getView(int position, View convertView, ViewGroup parent) {   
  21.         if (convertView == null) {   
  22.             convertView = inflater.inflate(R.layout.file_grid_item, parent, false);   
  23.         }   
  24.         TextView text = (TextView) convertView.findViewById(R.id.label);   
  25.         FileInfo info = mList[position];   
  26.         text.setText(info.name);   
  27.         text.setCompoundDrawablesWithIntrinsicBounds(0, info.icon, 00);   
  28.         text.setTag(info.path);   
  29.         return convertView;   
  30.     }   
  31.     public void updateData(final FileInfo[] list, final String path) {   
  32.         // If current path is not root, we have to show one more item for parent path.   
  33.         // Otherwise, do not;   
  34.         if(path.equals(PATH_ROOT)) {   
  35.             mList = list;   
  36.         } else {   
  37.             // If list is null just parent will be shown;   
  38.             if(list == null) {   
  39.                 mList = new FileInfo[1];   
  40.                 // Just one item for parent;   
  41.                 mList[0] = new FileInfo(PATH_PARENT_NAME, R.drawable.file_folder,   
  42.                         Utils.getParentPath(path));   
  43.             } else {   
  44.                 final int length = list.length;   
  45.                 mList = new FileInfo[length + 1];   
  46.                 System.arraycopy(list, 0, mList, 0, length);   
  47.                 // One more item for parent;   
  48.                 mList[length] = new FileInfo(PATH_PARENT_NAME, R.drawable.file_folder,   
  49.                         Utils.getParentPath(path));   
  50.             }   
  51.         }   
  52.         // Notify refresh itself;   
  53.         notifyDataSetChanged();   
  54.     }   
  55. }  

好了,今天主要的两个东西就是:

LoadFileInfoTask:主要用来取得文件信息。

GridView:主要用来显示文件信息,获得用户的点击之后判断是否显示下一级目录,或者加载文件。

来看看运行效果:

相关内容