• Android:增强目录选择器对话框


    介绍:

    每一次你需要在Android应用程序中选择一个SD卡目录,你都得加载一种目录选择器对话框,由它呈现图形界面以便你选择需要的目录。

    不幸的是,正如开发人员所预料的,Android不提供任何内置的目录选择器对话框。因此开发人员必须自己写。本文将讲述以增强创建对话框的能力,为Android SD卡实现简单的目录选择器对话框。该流程包含在一个单独的文件中并且不用任何额外资源,除了预定义的Android资源。

    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;
            }
        };
    }
    }
    

    用途实例

    如下实例表现如何通过点击按钮加载目录选择器对话框。先前选中的目录变为调用下一个对话框的初始目录。

    Android,移动设备开发

    Android,移动设备开发

    Android,移动设备开发

    结论:

    本文陈述了以创建新的目录来增强目录选择器对话框。

  • 相关阅读:
    Qt——组件位置随窗口变化
    (转) Qt 出现“undefined reference to `vtable for”原因总结
    在CentOS上安装和部署Shiny Server
    Hibernate实体生成JSON的问题及解决
    在CentOS上安装并运行SparkR
    CentOS 6主机上的RStudio Server安装步骤
    Oracle用户密码过期后重置SYS用户密码
    在CentOS中将/var等已有目录挂载到新添加的硬盘
    CentOS中的常用命令
    Java在Web项目中读取properties文件
  • 原文地址:https://www.cnblogs.com/elegant-dancer/p/3367703.html
Copyright © 2020-2023  润新知