Skip to content
This repository has been archived by the owner on Mar 9, 2022. It is now read-only.

Commit

Permalink
Add cancel button feature
Browse files Browse the repository at this point in the history
  • Loading branch information
jfmcode committed Dec 17, 2015
1 parent be656a1 commit 4c2c0e1
Show file tree
Hide file tree
Showing 22 changed files with 512 additions and 139 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/demo/.idea
/demo/.gradle
/demo/build
/demo/local.properties
/demo/aFileDialog/build
/demo/aFileDialogTesting/build

/library/.idea
/library/.gradle
/library/build
/library/local.properties
/library/app/build
Expand Down
8 changes: 5 additions & 3 deletions demo/aFileDialog/aFileDialog.iml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugAndroidTestSources" />
<afterSyncTasks>
<task>generateDebugAndroidTestSources</task>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
Expand All @@ -25,7 +27,7 @@
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="false">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
<exclude-output />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,13 @@ public class FileChooserActivity extends Activity implements FileChooser {
* a boolean that indicates if the user can create files.
*/
public static final String INPUT_CAN_CREATE_FILES = "input_can_create_files";


/**
* Constant used for represent the key of the bundle object (inside the start's intent) which contains
* a boolean that indicates if the cancel button must be show.
*/
public static final String INPUT_SHOW_CANCEL_BUTTON = "input_show_cancel_button";

/**
* Constant used for represent the key of the bundle object (inside the start's intent) which contains
* a regular expression which is going to be used as a filter to determine which files can be selected.
Expand Down Expand Up @@ -160,6 +166,7 @@ public void onCreate(Bundle savedInstanceState) {
if(extras.containsKey(INPUT_CAN_CREATE_FILES)) core.setCanCreateFiles(extras.getBoolean(INPUT_CAN_CREATE_FILES));
if(extras.containsKey(INPUT_LABELS)) core.setLabels((FileChooserLabels) extras.get(INPUT_LABELS));
if(extras.containsKey(INPUT_SHOW_CONFIRMATION_ON_CREATE)) core.setShowConfirmationOnCreate(extras.getBoolean(INPUT_SHOW_CONFIRMATION_ON_CREATE));
if(extras.containsKey(INPUT_SHOW_CANCEL_BUTTON)) core.setShowCancelButton(extras.getBoolean(INPUT_SHOW_CANCEL_BUTTON));
if(extras.containsKey(INPUT_SHOW_CONFIRMATION_ON_SELECT)) core.setShowConfirmationOnSelect(extras.getBoolean(INPUT_SHOW_CONFIRMATION_ON_SELECT));
if(extras.containsKey(INPUT_SHOW_FULL_PATH_IN_TITLE)) core.setShowFullPathInTitle(extras.getBoolean(INPUT_SHOW_FULL_PATH_IN_TITLE));
if(extras.containsKey(INPUT_USE_BACK_BUTTON_TO_NAVIGATE)) this.useBackButton = extras.getBoolean(INPUT_USE_BACK_BUTTON_TO_NAVIGATE);
Expand Down Expand Up @@ -193,6 +200,14 @@ public void onFileSelected(File file) {
finish();
}
});

// Add a listener for when the cancel button is pressed.
core.addListener(new FileChooserCore.OnCancelListener() {
public void onCancel() {
// Close activity.
FileChooserActivity.super.onBackPressed();
}
});
}

/** Called when the user push the 'back' button. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,13 @@ class FileChooserCore {
/**
* The listeners for the event of select a file.
*/
private List<OnFileSelectedListener> listeners;

private List<OnFileSelectedListener> fileSelectedListeners;

/**
* The listeners for the event of select a file.
*/
private List<OnCancelListener> cancelListeners;

/**
* A regular expression for filter the files.
*/
Expand All @@ -72,7 +77,12 @@ class FileChooserCore {
* A boolean indicating if the chooser is going to be used to select folders.
*/
private boolean folderMode;


/**
* A boolean indicating if the chooser is going to be used to select folders.
*/
private boolean showCancelButton;

/**
* A file that indicates the folder that is currently being displayed.
*/
Expand Down Expand Up @@ -122,7 +132,8 @@ class FileChooserCore {
public FileChooserCore(FileChooser fileChooser) {
// Initialize attributes.
this.chooser = fileChooser;
this.listeners = new LinkedList<OnFileSelectedListener>();
this.fileSelectedListeners = new LinkedList<OnFileSelectedListener>();
this.cancelListeners = new LinkedList<OnCancelListener>();
this.filter = null;
this.showOnlySelectable = false;
this.setCanCreateFiles(false);
Expand All @@ -132,13 +143,16 @@ public FileChooserCore(FileChooser fileChooser) {
this.showConfirmationOnCreate = false;
this.showConfirmationOnSelect = false;
this.showFullPathInTitle = false;

// Add listener for the buttons.
this.showCancelButton = false;

// Add listener for the buttons.
LinearLayout root = this.chooser.getRootLayout();
Button addButton = (Button) root.findViewById(R.id.buttonAdd);
addButton.setOnClickListener(addButtonClickListener);
Button okButton = (Button) root.findViewById(R.id.buttonOk);
okButton.setOnClickListener(okButtonClickListener);
Button cancelButton = (Button) root.findViewById(R.id.buttonCancel);
cancelButton.setOnClickListener(cancelButtonClickListener);
}

// ----- Events methods ----- //
Expand Down Expand Up @@ -178,7 +192,7 @@ public void onClick(DialogInterface dialog, int whichButton) {
// Verify if a value has been entered.
if(fileName != null && fileName.length() > 0) {
// Notify the listeners.
FileChooserCore.this.notifyListeners(FileChooserCore.this.currentFolder, fileName);
FileChooserCore.this.notifyFileListeners(FileChooserCore.this.currentFolder, fileName);
}
}
});
Expand All @@ -199,10 +213,20 @@ public void onClick(DialogInterface dialog, int whichButton) {
private View.OnClickListener okButtonClickListener = new View.OnClickListener() {
public void onClick(View v) {
// Notify the listeners.
FileChooserCore.this.notifyListeners(FileChooserCore.this.currentFolder, null);
FileChooserCore.this.notifyFileListeners(FileChooserCore.this.currentFolder, null);
}
};


/**
* Implementation of the click listener for when the cancel button is clicked.
*/
private View.OnClickListener cancelButtonClickListener = new View.OnClickListener() {
public void onClick(View v) {
// Notify the listeners.
FileChooserCore.this.notifyCancelListeners();
}
};

/**
* Implementation of the click listener for when a file item is clicked.
*/
Expand All @@ -215,7 +239,7 @@ public void onClick(FileItem source) {
FileChooserCore.this.loadFolder(file);
} else {
// Notify the listeners.
FileChooserCore.this.notifyListeners(file, null);
FileChooserCore.this.notifyFileListeners(file, null);
}
}
};
Expand All @@ -226,7 +250,7 @@ public void onClick(FileItem source) {
* @param listener The listener to add.
*/
public void addListener(OnFileSelectedListener listener) {
this.listeners.add(listener);
this.fileSelectedListeners.add(listener);
}

/**
Expand All @@ -235,16 +259,35 @@ public void addListener(OnFileSelectedListener listener) {
* @param listener The listener to remove.
*/
public void removeListener(OnFileSelectedListener listener) {
this.listeners.remove(listener);
}

/**
* Removes all the listeners for the event of a file selected.
*/
public void removeAllListeners() {
this.listeners.clear();
this.fileSelectedListeners.remove(listener);
}


/**
* Add a listener for the event of a file selected.
*
* @param listener The listener to add.
*/
public void addListener(OnCancelListener listener) {
this.cancelListeners.add(listener);
}

/**
* Removes a listener for the event of a file selected.
*
* @param listener The listener to remove.
*/
public void removeListener(OnCancelListener listener) {
this.cancelListeners.remove(listener);
}

/**
* Removes all the listeners for the event of a file selected.
*/
public void removeAllListeners() {
this.fileSelectedListeners.clear();
this.cancelListeners.clear();
}

/**
* Interface definition for a callback to be invoked when a file is selected.
*/
Expand All @@ -264,14 +307,33 @@ public interface OnFileSelectedListener {
*/
void onFileSelected(File folder, String name);
}


/**
* Interface definition for a callback to be invoked when the cancel button is clicked.
*/
public interface OnCancelListener {
/**
* Called when the cancel button is clicked.
*/
void onCancel();
}

/**
* Notify to all listeners that the cancel button has been pressed.
*/
private void notifyCancelListeners() {
for(int i=0; i<FileChooserCore.this.cancelListeners.size(); i++) {
FileChooserCore.this.cancelListeners.get(i).onCancel();
}
}

/**
* Notify to all listeners that a file has been selected or created.
*
* @param file The file or folder selected or the folder in which the file must be created.
* @param name The name of the file that must be created or 'null' if a file was selected (instead of being created).
*/
private void notifyListeners(final File file, final String name) {
private void notifyFileListeners(final File file, final String name) {
// Determine if a file has been selected or created.
final boolean creation = name != null && name.length() > 0;

Expand Down Expand Up @@ -301,11 +363,11 @@ private void notifyListeners(final File file, final String name) {
alert.setPositiveButton(posButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Notify to listeners.
for(int i=0; i<FileChooserCore.this.listeners.size(); i++) {
for(int i=0; i<FileChooserCore.this.fileSelectedListeners.size(); i++) {
if(creation) {
FileChooserCore.this.listeners.get(i).onFileSelected(file, name);
FileChooserCore.this.fileSelectedListeners.get(i).onFileSelected(file, name);
} else {
FileChooserCore.this.listeners.get(i).onFileSelected(file);
FileChooserCore.this.fileSelectedListeners.get(i).onFileSelected(file);
}
}
}
Expand All @@ -320,11 +382,11 @@ public void onClick(DialogInterface dialog, int whichButton) {
alert.show();
} else {
// Notify to listeners.
for(int i=0; i<FileChooserCore.this.listeners.size(); i++) {
for(int i=0; i<FileChooserCore.this.fileSelectedListeners.size(); i++) {
if(creation) {
FileChooserCore.this.listeners.get(i).onFileSelected(file, name);
FileChooserCore.this.fileSelectedListeners.get(i).onFileSelected(file, name);
} else {
FileChooserCore.this.listeners.get(i).onFileSelected(file);
FileChooserCore.this.fileSelectedListeners.get(i).onFileSelected(file);
}
}
}
Expand Down Expand Up @@ -362,7 +424,7 @@ public void setShowFullPathInTitle(boolean show) {
/**
* Defines the value of the labels.
*
* @param label The labels.
* @param labels The labels.
*/
public void setLabels(FileChooserLabels labels) {
this.labels = labels;
Expand All @@ -379,7 +441,12 @@ public void setLabels(FileChooserLabels labels) {
if(labels.labelSelectButton != null) {
Button okButton = (Button) root.findViewById(R.id.buttonOk);
okButton.setText(labels.labelSelectButton);
}
}

if(labels.labelCancelButton != null) {
Button cancelButton = (Button) root.findViewById(R.id.buttonCancel);
cancelButton.setText(labels.labelCancelButton);
}
}
}

Expand Down Expand Up @@ -413,7 +480,19 @@ public void setFolderMode(boolean folderMode) {
// Reload the list of files.
this.loadFolder(this.currentFolder);
}


/**
* Defines if the chooser is going to be used to select folders, instead of files.
*
* @param showCancelButton 'true' for show the cancel button or 'false' for not showing it.
*/
public void setShowCancelButton(boolean showCancelButton) {
this.showCancelButton = showCancelButton;

// Show or hide the 'Cancel' button.
updateButtonsLayout();
}

/**
* Defines if the user can create files, instead of only select files.
*
Expand Down Expand Up @@ -455,37 +534,19 @@ public File getCurrentFolder() {
private void updateButtonsLayout() {
// Get the buttons layout.
LinearLayout root = this.chooser.getRootLayout();
LinearLayout buttonsLayout = (LinearLayout) root.findViewById(R.id.linearLayoutButtons);

// Verify if the 'Add' button is visible or not.
View addButton = root.findViewById(R.id.buttonAdd);
addButton.setVisibility(this.canCreateFiles? View.VISIBLE : View.INVISIBLE);
addButton.getLayoutParams().width = this.canCreateFiles? ViewGroup.LayoutParams.MATCH_PARENT : 0;
addButton.setVisibility(this.canCreateFiles? View.VISIBLE : View.GONE);

// Verify if the 'Ok' button is visible or not.
View okButton = root.findViewById(R.id.buttonOk);
okButton.setVisibility(this.folderMode? View.VISIBLE : View.INVISIBLE);
okButton.getLayoutParams().width = this.folderMode? ViewGroup.LayoutParams.MATCH_PARENT : 0;

// If both buttons are invisible, hide the layout.
ViewGroup.LayoutParams params = buttonsLayout.getLayoutParams();
if(this.canCreateFiles || this.folderMode) {
// Show the layout.
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;

// If only the 'Ok' button is visible, put him first. Otherwise, put 'Add' first.
buttonsLayout.removeAllViews();
if(this.folderMode && !this.canCreateFiles) {
buttonsLayout.addView(okButton);
buttonsLayout.addView(addButton);
} else {
buttonsLayout.addView(addButton);
buttonsLayout.addView(okButton);
}
} else {
// Hide the layout.
params.height = 0;
}
okButton.setVisibility(this.folderMode? View.VISIBLE : View.GONE);

// Verify if the 'Cancel' button is visible or not.
View cancelButton = root.findViewById(R.id.buttonCancel);
cancelButton.setVisibility(this.showCancelButton? View.VISIBLE : View.GONE);

}

/**
Expand Down
Loading

0 comments on commit 4c2c0e1

Please sign in to comment.