ファイル選択ダイアログ ( AlertDialog + ListView )

解説

標準では、ファイル選択ダイアログに関する関数、クラスは用意されていないので、自作します。

実現方法としては、AlertDialog内に、ListViewを表示する方法で実現します。

ファイル選択ダイアログに関するクラスとしては、3つのクラスを作成します。
・「AlertDialog内にListViewを表示する」ファイル選択ダイアログクラス
・「ListViewの表示要素を管理する」ファイル情報配列アダプタクラス
・「ListViewで表示するときの一要素にあたる」ファイル情報クラス

実装

アプリの仕様

プロジェクトの作成

(開発環境としては、Android Studio 2.3.3 を使用しています)

(この設定でプロジェクトを作成しなければいけない、というわけではありません。)

「Welcome」画面の「Start a new Android Studio project」をクリックします。


Application nameに、「FileSelectionDialogTest」と入力します。
Company domainに、会社のドメイン名を指定します。
Project locationに、プロジェクトを保存するフォルダパスを指定します。
「Next」ボタンを押します。


Minimum SDKを選択します(たとえば、「API19: Android 4.4 (KitKat)」)。
「Next」ボタンを押します。


Empty Activity」を選択し、「Next」ボタンを押します。


(変更なし)
「Finish」を押します。

しばらく待ちます。
Android Studio のステータスバーに「Gradle build finished in ・・・」と出るまで待ちます。

以上で、プロジェクトができました。

クラスファイルの作成

ファイル選択ダイアログに関する以下の3つのクラスを作成していきます。
①「AlertDialog内にListViewを表示する」ファイル選択ダイアログクラス
②「ListViewの表示要素を管理する」ファイル情報配列アダプタクラス
③「ListViewで表示するときの一要素にあたる」ファイル情報クラス

ここで、③は②からのみ使用されるクラスであり、②は①からのみ使用されるクラスです。

①②③のクラスをそれぞれ個別のファイルとして作成することもできますが、可搬性・移植性を考慮し、ここでは、①②③をまとめて1つのファイルで作成することとします。
すなわち、①のクラスの内部クラスとして②③のクラスを作成することとします。

「Project」ペインの「app > java > ドメイン.fileselectiondialogtest」を右クリックします。
右クリックメニュー「New > Java Class」を選択します。


Nameに、「FileSelectionDialog」と入力します。
「OK」ボタンを押します。

ファイル情報クラスの追加

「ListViewで表示するときの一要素にあたる」ファイル情報クラスを追加します。

ファイル情報クラスの仕事は、
① ファイル・ディレクトリの表示名とFileオブジェクトの管理
② ソート用の比較関数の提供
です。

「① ファイル・ディレクトリの表示名とFileオブジェクトの管理」のために、メンバ変数、アクセサ関数を追加します。
「② ソート用の比較関数の提供」のために、Comparable<FileInfo> のインターフェースを実装します。
(クラス名の後ろに、implements Comparable<FileInfo> を追加し、インターフェースで宣言されている関数である compareTo関数を追加します。)

ファイル選択ダイアログクラスに、内部クラスとしてファイル情報クラスを追加します。

ファイル選択ダイアログクラス全体としては、以下のようにします。



「Cannot resolve symbol」エラーは、「Alt + Enter」で、必要なクラスをimportします。
リビルドし、エラー、警告がないことを確認します。

ファイル情報配列アダプタクラスの追加

「ListViewの表示要素を管理する」ファイル情報配列アダプタクラスを追加します。

ファイル情報配列アダプタクラスの仕事は、
① ファイル情報リストの委譲、管理
② ListViewのリスト表示における一要素のビューの生成
です。

「① ファイル情報リストの委譲、管理」のために、メンバ変数、コンストラクタ、アクセサ関数を追加します。
「② ListViewのリスト表示における一要素のビューの生成」のために、getView関数をオーバーライドし、処理を実装します。

ファイル選択ダイアログクラスの末尾に、内部クラスとしてファイル情報配列アダプタクラスを追加します。

ファイル選択ダイアログクラス全体としては、以下のようにします。



「Cannot resolve symbol」エラーは、「Alt + Enter」で、必要なクラスをimportします。
リビルドし、エラー、警告がないことを確認します。

ファイル選択ダイアログクラスの追加

「AlertDialog内にListViewを表示する」ファイル選択ダイアログクラスを追加します。

ファイル選択ダイアログクラスの仕事は、
① ダイアログの作成と表示
② ダイアログのListView内の項目をクリックしたときの処理
③ 選択したファイルの情報を呼び出し元に返すためのしくみの提供
です。

「① ダイアログの作成と表示」のために、showという関数を追加します。
「② ダイアログのListView内の項目をクリックしたときの処理」のために、android.widget.AdapterView.OnItemClickListener のインターフェースを実装します。
(クラス名の後ろに、implements AdapterView.OnItemClickListener を追加し、実装するインターフェースを指定します。指定したインターフェースで宣言されている関数である onItemClick関数を追加します。)
「③ 選択したファイルの情報を呼び出し元に返すためのしくみの提供」のために、リスナーインターフェースを追加し、onFileSelectという関数を宣言します。

メンバ変数、コンストラクタも追加します。

ファイル選択ダイアログクラス全体としては、以下のようにします。



「Cannot resolve symbol」エラーは、「Alt + Enter」で、必要なクラスをimportします。
リビルドし、エラー、警告がないことを確認します。

メインアクティビティクラスの実装

ファイル選択ダイアログに関する3つのクラスが出来たので、メインアクティビティに、ファイル選択ダイアログ呼び出しの処理を実装します。

メインアクティビティクラスの仕事は、
① タイトルバー右のオプションメニューに、「Select File...」 というメニュー項目が表示される。
② 「Select File...」というメニュー項目を選択すると、ファイル選択ダイアログが表示される。
③ ファイル名をクリックされた場合に、選択したファイルパス名をトーストにて表示する。
です。

「① タイトルバー右のオプションメニューに、「Select File...」 というメニュー項目が表示される。」のために、onCreateOptionsMenu関数をオーバーライドし、処理を実装します。
「② 「Select File...」というメニュー項目を選択すると、ファイル選択ダイアログが表示される。」のために、onOptionsItemSelected関数をオーバーライドし、処理を実装します。
「③ ファイル名をクリックされた場合に、選択したファイルパス名をトーストにて表示する。」のために、FileSelectionDialog.OnFileSelectListener のインターフェースを実装します。
(クラス名の後ろに、implements FileSelectionDialog.OnFileSelectListener を追加し、インターフェースで宣言されている関数である onFileSelect関数を追加します。)

メンバ変数も追加します。

メインアクティビティクラス全体としては、以下のようにします。



「Cannot resolve symbol」エラーは、「Alt + Enter」で、必要なクラスをimportします。
リビルドし、エラー、警告がないことを確認します。

ファイルのリストを取得するためのパーミッションの宣言

ファイルのリストを取得するためには、「READ_EXTERNAL_STORAGE」パーミッションが必要です。
マニフェストファイルに、「READ_EXTERNAL_STORAGE」パーミッションの宣言を追加します。

「Project」ペインの「app > manifests > AndroidManifest.xml」を開きます。

以下のパーミッション宣言を追加します。



「AndroidManifest.xml」全体としては、以下のようにします。

実行時のパーミッションリクエスト

ファイルのリストを取得するためには、「READ_EXTERNAL_STORAGE」パーミッションが必要です。
実行時に、「READ_EXTERNAL_STORAGE」パーミッションが付与されているかをチェックし、付与されていない場合にはパーミッションをリクエストします。

メインアクティビティクラスの末尾に、onResume関数、requestReadExternalStoragePermission関数、onRequestPermissionsResult関数を追加します。
また、定数宣言部に、「外部ストレージ読み込みパーミッション要求時の識別コード」定数を追加します。



「Cannot resolve symbol」エラーは、「Alt + Enter」で、必要なクラスをimportします。
リビルドし、エラー、警告がないことを確認します。

実行

Android端末にて、動作確認。

起動時に、「READ_EXTERNAL_STORAGE」パーミッションが付与されていない場合は、「READ_EXTERNAL_STORAGE」パーミッションリクエストダイアログが表示されます。「許可」をタップすると、起動します。「許可しない」をタップすると、起動しません。


起動直後


タイトルバー右のオプションメニューをタップすると、「Select File...」 というメニュー項目が表示されます。


「Select File..」というメニュー項目を選択すると、ファイル選択ダイアログが表示されます。


ディレクトリ名をクリックすると、一階層下のディレクトリ・ファイルのリストが表示されます。


ファイル名をクリックすると、ファイルパス名が、トーストで表示されます。

ダウンロード

テストプロジェクト
github.com上のリポジトリページ

関連ページ

ファイル選択ダイアログ ( AlertDialog + ListView ) - 本ページ

ファイル選択ダイアログ ( AlertDialog + ListView + 拡張子フィルタ )


ファイル選択ダイアログ ( AlertDialog + ListView + 拡張子フィルタ + 複数ファイル選択 )

ファイル選択アクティビティ ( Activity + ListView )

ファイル選択アクティビティ ( Activity + ListView + 拡張子フィルタ )

ファイル選択アクティビティ ( Activity + ListView + 拡張子フィルタ + 複数ファイル選択 )