原创|行业资讯|编辑:郝浩|2013-10-12 09:26:21.000|阅读 1545 次
概述:本文陈述了以创建新的目录来增强目录选择器对话框。
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
介绍:
每一次你需要在Android应用程序中选择一个SD卡目录,你都得加载一种目录选择器对话框,由它呈现图形界面以便你选择需要的目录。
不幸的是,正如开发人员所预料的,Android不提供任何内置的目录选择器对话框。因此开发人员必须自己写。本文将讲述以增强创建对话框的能力,为Android SD卡实现简单的目录选择器对话框。该流程包含在一个单独的文件中并且不用任何额外资源,除了预定义的Android资源。

执行代码
目录选择器对话框是基于AlertDialog,由子目录的ListView所供给。当前目录路径是显示在AlertDialog标题上。通过点击子目录ListView中的项目完成导航向前到一个目录,然后通过按住“返回”键返回。清单中的子目录是按名称分类的。当通过按住OK键选中需要的目录,一个“注册回调”被唤起,它由已选择目录的完整路径所供给。
代码包含在一个单独的文件DirectoryChooserDialog.java中。它以当前目录的子目录的ListView 加载AlertDialog 并保持追踪导航目录。
执行DirectoryChooserDialog 类定义如下回调界面。
// Callback interface for selected directory
public interface ChosenDirectoryListener
{ public void onChosenDir(String chosenDir);
}
一个回调可以被注册于DirectoryChooserDialog类构造函数中。
public DirectoryChooserDialog(Context context, ChosenDirectoryListener chosenDirectoryListener);
通过默认创建能力,新目录能够被运用(通过点击“新文件夹”按钮),它可以通过setNewFolderEnabled的方式关闭,当禁用新文件夹按钮隐藏时。
///////////////////////////////////////////////////////////////////////
// setNewFolderEnabled() - enable/disable new folder button
///////////////////////////////////////////////////////////////////////
public void setNewFolderEnabled(boolean isNewFolderEnabled)
{
m_isNewFolderEnabled = isNewFolderEnabled;
}
public boolean getNewFolderEnabled()
{
return m_isNewFolderEnabled;
}
DirectoryChooserDialog指定两个公共chooseDirectory 方式来加载目录选择器对话框。一个带有初始目录参数;另一个没有。默认初始目录是SD卡的根目录。
////////////////////////////////////////////////////////////////////// // chooseDirectory() - load directory chooser dialog for initial // default sdcard root directory ////////////////////////////////////////////////////////////////////// public void chooseDirectory(); //////////////////////////////////////////////////////////////////////////////// // chooseDirectory(String dir) - load directory chooser dialog for initial // input 'dir' directory //////////////////////////////////////////////////////////////////////////////// public void chooseDirectory(String dir);
DirectoryChooserDialog 类全面执行如下:
// DirectoryChooserDialog.java
package com.example.directorychooser;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnKeyListener;
import android.os.Environment;
import android.text.Editable;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class DirectoryChooserDialog
{
private boolean m_isNewFolderEnabled = true;
private String m_sdcardDirectory = "";
private Context m_context;
private TextView m_titleView;
private String m_dir = "";
private List<String> m_subdirs = null;
private ChosenDirectoryListener m_chosenDirectoryListener = null;
private ArrayAdapter<String> m_listAdapter = null;
//////////////////////////////////////////////////////
// Callback interface for selected directory
//////////////////////////////////////////////////////
public interface ChosenDirectoryListener
{
public void onChosenDir(String chosenDir);
}
public DirectoryChooserDialog(Context context, ChosenDirectoryListener chosenDirectoryListener)
{
m_context = context;
m_sdcardDirectory = Environment.getExternalStorageDirectory().getAbsolutePath();
m_chosenDirectoryListener = chosenDirectoryListener;
try
{
m_sdcardDirectory = new File(m_sdcardDirectory).getCanonicalPath();
}
catch (IOException ioe)
{
}
}
///////////////////////////////////////////////////////////////////////
// setNewFolderEnabled() - enable/disable new folder button
///////////////////////////////////////////////////////////////////////
public void setNewFolderEnabled(boolean isNewFolderEnabled)
{
m_isNewFolderEnabled = isNewFolderEnabled;
}
public boolean getNewFolderEnabled()
{
return m_isNewFolderEnabled;
}
///////////////////////////////////////////////////////////////////////
// chooseDirectory() - load directory chooser dialog for initial
// default sdcard directory
///////////////////////////////////////////////////////////////////////
public void chooseDirectory()
{
// Initial directory is sdcard directory
chooseDirectory(m_sdcardDirectory);
}
////////////////////////////////////////////////////////////////////////////////
// chooseDirectory(String dir) - load directory chooser dialog for initial
// input 'dir' directory
////////////////////////////////////////////////////////////////////////////////
public void chooseDirectory(String dir)
{
File dirFile = new File(dir);
if (! dirFile.exists() || ! dirFile.isDirectory())
{
dir = m_sdcardDirectory;
}
try
{
dir = new File(dir).getCanonicalPath();
}
catch (IOException ioe)
{
return;
}
m_dir = dir;
m_subdirs = getDirectories(dir);
class DirectoryOnClickListener implements DialogInterface.OnClickListener
{
public void onClick(DialogInterface dialog, int item)
{
// Navigate into the sub-directory
m_dir += "/" + ((AlertDialog) dialog).getListView().getAdapter().getItem(item);
updateDirectory();
}
}
AlertDialog.Builder dialogBuilder =
createDirectoryChooserDialog(dir, m_subdirs, new DirectoryOnClickListener());
dialogBuilder.setPositiveButton("OK", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
// Current directory chosen
if (m_chosenDirectoryListener != null)
{
// Call registered listener supplied with the chosen directory
m_chosenDirectoryListener.onChosenDir(m_dir);
}
}
}).setNegativeButton("Cancel", null);
final AlertDialog dirsDialog = dialogBuilder.create();
dirsDialog.setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN)
{
// Back button pressed
if ( m_dir.equals(m_sdcardDirectory) )
{
// The very top level directory, do nothing
return false;
}
else
{
// Navigate back to an upper directory
m_dir = new File(m_dir).getParent();
updateDirectory();
}
return true;
}
else
{
return false;
}
}
});
// Show directory chooser dialog
dirsDialog.show();
}
private boolean createSubDir(String newDir)
{
File newDirFile = new File(newDir);
if (! newDirFile.exists() )
{
return newDirFile.mkdir();
}
return false;
}
private List<String> getDirectories(String dir)
{
List<String> dirs = new ArrayList<String>();
try
{
File dirFile = new File(dir);
if (! dirFile.exists() || ! dirFile.isDirectory())
{
return dirs;
}
for (File file : dirFile.listFiles())
{
if ( file.isDirectory() )
{
dirs.add( file.getName() );
}
}
}
catch (Exception e)
{
}
Collections.sort(dirs, new Comparator<String>()
{
public int compare(String o1, String o2)
{
return o1.compareTo(o2);
}
});
return dirs;
}
private AlertDialog.Builder createDirectoryChooserDialog(String title, List<String> listItems,
DialogInterface.OnClickListener onClickListener)
{
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(m_context);
// Create custom view for AlertDialog title containing
// current directory TextView and possible 'New folder' button.
// Current directory TextView allows long directory path to be wrapped to multiple lines.
LinearLayout titleLayout = new LinearLayout(m_context);
titleLayout.setOrientation(LinearLayout.VERTICAL);
m_titleView = new TextView(m_context);
m_titleView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
m_titleView.setTextAppearance(m_context, android.R.style.TextAppearance_Large);
m_titleView.setTextColor( m_context.getResources().getColor(android.R.color.white) );
m_titleView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
m_titleView.setText(title);
Button newDirButton = new Button(m_context);
newDirButton.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
newDirButton.setText("New folder");
newDirButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
final EditText input = new EditText(m_context);
// Show new folder name input dialog
new AlertDialog.Builder(m_context).
setTitle("New folder name").
setView(input).setPositiveButton("OK", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
Editable newDir = input.getText();
String newDirName = newDir.toString();
// Create new directory
if ( createSubDir(m_dir + "/" + newDirName) )
{
// Navigate into the new directory
m_dir += "/" + newDirName;
updateDirectory();
}
else
{
Toast.makeText(
m_context, "Failed to create '" + newDirName +
"' folder", Toast.LENGTH_SHORT).show();
}
}
}).setNegativeButton("Cancel", null).show();
}
});
if (! m_isNewFolderEnabled)
{
newDirButton.setVisibility(View.GONE);
}
titleLayout.addView(m_titleView);
titleLayout.addView(newDirButton);
dialogBuilder.setCustomTitle(titleLayout);
m_listAdapter = createListAdapter(listItems);
dialogBuilder.setSingleChoiceItems(m_listAdapter, -1, onClickListener);
dialogBuilder.setCancelable(false);
return dialogBuilder;
}
private void updateDirectory()
{
m_subdirs.clear();
m_subdirs.addAll( getDirectories(m_dir) );
m_titleView.setText(m_dir);
m_listAdapter.notifyDataSetChanged();
}
private ArrayAdapter<String> createListAdapter(List<String> items)
{
return new ArrayAdapter<String>(m_context,
android.R.layout.select_dialog_item, android.R.id.text1, items)
{
@Override
public View getView(int position, View convertView,
ViewGroup parent)
{
View v = super.getView(position, convertView, parent);
if (v instanceof TextView)
{
// Enable list item (directory) text wrapping
TextView tv = (TextView) v;
tv.getLayoutParams().height = LayoutParams.WRAP_CONTENT;
tv.setEllipsize(null);
}
return v;
}
};
}
}
用途实例
如下实例表现如何通过点击按钮加载目录选择器对话框。先前选中的目录变为调用下一个对话框的初始目录。



结论:
本文陈述了以创建新的目录来增强目录选择器对话框。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@ke049m.cn
文章转载自:慧都控件网