Browse Source

Fixed #315. You no longer need to set item click listeners separately when using custom adapters either.

Aidan Follestad 10 years ago
parent
commit
d6f933d615

+ 16 - 11
README.md

@@ -271,23 +271,28 @@ every time the user selects an item.
 ### Custom List Dialogs
 
 Like Android's native dialogs, you can also pass in your own adapter via `.adapter()` to customize
-exactly how you want your list to work. You also have access to the dialog's list via `getListView()` method.
+exactly how you want your list to work.
 
 ```java
-MaterialDialog dialog = new MaterialDialog.Builder(this)
+new MaterialDialog.Builder(this)
         .title(R.string.socialNetworks)
         .adapter(new ButtonItemAdapter(this, R.array.socialNetworks))
+        .itemsCallback(new MaterialDialog.ListCallback() {
+            @Override
+            public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
+            }
+        }).show();
+```
+
+If you need access to the `ListView`, you can use the `MaterialDialog` instance.
+
+```java
+MaterialDialog dialog = new MaterialDialog.Builder(this)
+        ...
         .build();
 
-ListView listView = dialog.getListView();
-if (listView != null) {
-    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-        @Override
-        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            Toast.makeText(MainActivity.this, "Clicked item " + position, Toast.LENGTH_SHORT).show();
-        }
-    });
-}
+ListView list = dialog.getListView();
+// Do something with it
 
 dialog.show();
 ```

+ 2 - 2
library/build.gradle

@@ -9,7 +9,7 @@ android {
         minSdkVersion 8
         targetSdkVersion 22
         versionCode 1
-        versionName "0.6.3.5"
+        versionName "0.6.4.0"
     }
     lintOptions {
         abortOnError false
@@ -27,7 +27,7 @@ publish {
     userOrg = 'drummer-aidan'
     groupId = 'com.afollestad'
     artifactId = 'material-dialogs'
-    version = '0.6.3.5'
+    version = '0.6.4.0'
     description = 'A library for implementing Material design styled dialogs across all versions of Android.'
     website = 'https://github.com/afollestad/material-dialogs'
     issueTracker = "${website}/issues"

+ 25 - 5
library/src/main/java/com/afollestad/materialdialogs/AlertDialogWrapper.java

@@ -13,8 +13,6 @@ import android.support.annotation.StringRes;
 import android.view.View;
 import android.widget.ListAdapter;
 
-import com.afollestad.materialdialogs.MaterialDialog;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -33,6 +31,7 @@ public class AlertDialogWrapper {
         private DialogInterface.OnClickListener neutralDialogListener;
 
         private DialogInterface.OnClickListener onClickListener;
+        private DialogInterface.OnClickListener onClickListenerAdapter;
 
         public Builder(@NonNull Context context) {
             builder = new MaterialDialog.Builder(context);
@@ -120,7 +119,7 @@ public class AlertDialogWrapper {
             return this;
         }
 
-        public Builder setItems(@ArrayRes int itemsId, final DialogInterface.OnClickListener listener) {
+        public Builder setItems(@ArrayRes int itemsId, DialogInterface.OnClickListener listener) {
             builder.items(itemsId);
             onClickListener = listener;
             return this;
@@ -132,14 +131,35 @@ public class AlertDialogWrapper {
             return this;
         }
 
+        /**
+         * @param adapter The adapter to set.
+         * @return An instance of the Builder for chaining.
+         * @deprecated Use {@link #setAdapter(ListAdapter, DialogInterface.OnClickListener)} instead.
+         */
+        @Deprecated
         public Builder setAdapter(ListAdapter adapter) {
+            return setAdapter(adapter, null);
+        }
+
+        /**
+         * @param adapter  The adapter to set.
+         * @param listener The listener called when list items are clicked.
+         * @return An instance of the Builder for chaining.
+         */
+        public Builder setAdapter(ListAdapter adapter, final DialogInterface.OnClickListener listener) {
             builder.adapter = adapter;
+            builder.listCallbackCustom = new MaterialDialog.ListCallback() {
+                @Override
+                public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) {
+                    listener.onClick(dialog, which);
+                }
+            };
             return this;
         }
 
         public AlertDialog create() {
             addButtonsCallback();
-            addItemsCallBack();
+            addListCallbacks();
             return builder.build();
         }
 
@@ -149,7 +169,7 @@ public class AlertDialogWrapper {
             return dialog;
         }
 
-        private void addItemsCallBack() {
+        private void addListCallbacks() {
             if (onClickListener != null) {
                 builder.itemsCallback(new MaterialDialog.ListCallback() {
                     @Override

+ 55 - 35
library/src/main/java/com/afollestad/materialdialogs/MaterialDialog.java

@@ -61,7 +61,7 @@ import java.util.List;
 /**
  * @author Aidan Follestad (afollestad)
  */
-public class MaterialDialog extends DialogBase implements View.OnClickListener {
+public class MaterialDialog extends DialogBase implements View.OnClickListener, AdapterView.OnItemClickListener {
 
     protected final View view;
     protected final Builder mBuilder;
@@ -504,37 +504,7 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
         FrameLayout listViewContainer = (FrameLayout) view.findViewById(R.id.contentListViewFrame);
         listViewContainer.setVisibility(View.VISIBLE);
         listView.setAdapter(mBuilder.adapter);
-
-        if (listType != null) {
-            // Only set listener for 1st-party adapter, leave custom adapter implementation to user with getListView()
-            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-                @Override
-                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-
-                    if (listType == ListType.MULTI) {
-                        // Keep our selected items up to date
-                        boolean isChecked = !((CheckBox) view.findViewById(R.id.control)).isChecked();  // Inverted because the view's click listener is called before the check is toggled
-                        boolean previouslySelected = selectedIndicesList.contains(position);
-                        if (isChecked) {
-                            if (!previouslySelected) {
-                                selectedIndicesList.add(position);
-                            }
-                        } else if (previouslySelected) {
-                            selectedIndicesList.remove(Integer.valueOf(position));
-                        }
-                    } else if (listType == ListType.SINGLE) {
-                        // Keep our selected item up to date
-                        if (mBuilder.selectedIndex != position) {
-                            mBuilder.selectedIndex = position;
-                            ((MaterialDialogAdapter) mBuilder.adapter).notifyDataSetChanged();
-                        }
-                    }
-
-                    onClick(view);
-                }
-            });
-        }
-
+        listView.setOnItemClickListener(this);
     }
 
     /**
@@ -639,6 +609,39 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
         return canAdapterViewScroll(listView);
     }
 
+    @Override
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        if (listType != null) {
+            // MaterialDialogAdapter, used for built-in adapters
+            if (listType == ListType.MULTI) {
+                // Keep our selected items up to date
+                boolean isChecked = !((CheckBox) view.findViewById(R.id.control)).isChecked();  // Inverted because the view's click listener is called before the check is toggled
+                boolean previouslySelected = selectedIndicesList.contains(position);
+                if (isChecked) {
+                    if (!previouslySelected) {
+                        selectedIndicesList.add(position);
+                    }
+                } else if (previouslySelected) {
+                    selectedIndicesList.remove(Integer.valueOf(position));
+                }
+            } else if (listType == ListType.SINGLE) {
+                // Keep our selected item up to date
+                if (mBuilder.selectedIndex != position) {
+                    mBuilder.selectedIndex = position;
+                    ((MaterialDialogAdapter) mBuilder.adapter).notifyDataSetChanged();
+                }
+            }
+            onClick(view);
+        } else {
+            // Custom adapter
+            if (mBuilder.listCallbackCustom != null) {
+                CharSequence text = null;
+                if (view instanceof TextView)
+                    text = ((TextView) view).getText();
+                mBuilder.listCallbackCustom.onSelection(this, view, position, text);
+            }
+        }
+    }
 
     public static class NotImplementedException extends Error {
         public NotImplementedException(String message) {
@@ -923,6 +926,7 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
         protected ListCallback listCallback;
         protected ListCallback listCallbackSingle;
         protected ListCallbackMulti listCallbackMulti;
+        protected ListCallback listCallbackCustom;
         protected boolean alwaysCallMultiChoiceCallback = false;
         protected boolean alwaysCallSingleChoiceCallback = false;
         protected Theme theme = Theme.LIGHT;
@@ -1473,13 +1477,29 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
         /**
          * Sets a custom {@link android.widget.ListAdapter} for the dialog's list
          *
+         * @param adapter The adapter to set to the list.
          * @return This Builder object to allow for chaining of calls to set methods
+         * @deprecated Use {@link #adapter(ListAdapter, ListCallback)} instead.
          */
+        @Deprecated
         public Builder adapter(@NonNull ListAdapter adapter) {
             this.adapter = adapter;
             return this;
         }
 
+        /**
+         * Sets a custom {@link android.widget.ListAdapter} for the dialog's list
+         *
+         * @param adapter  The adapter to set to the list.
+         * @param callback The callback invoked when an item in the list is selected.
+         * @return This Builder object to allow for chaining of calls to set methods
+         */
+        public Builder adapter(@NonNull ListAdapter adapter, ListCallback callback) {
+            this.adapter = adapter;
+            this.listCallbackCustom = callback;
+            return this;
+        }
+
         public Builder limitIconToDefaultSize() {
             this.limitIconToDefaultSize = true;
             return this;
@@ -1883,7 +1903,7 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
         }
     }
 
-    private static enum ListType {
+    private enum ListType {
         REGULAR, SINGLE, MULTI;
 
         public static int getLayoutForType(ListType type) {
@@ -1900,11 +1920,11 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
         }
     }
 
-    public static interface ListCallback {
+    public interface ListCallback {
         void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text);
     }
 
-    public static interface ListCallbackMulti {
+    public interface ListCallbackMulti {
         void onSelection(MaterialDialog dialog, Integer[] which, CharSequence[] text);
     }
 

+ 2 - 2
sample/build.gradle

@@ -8,8 +8,8 @@ android {
         applicationId "com.afollestad.materialdialogssample"
         minSdkVersion 14
         targetSdkVersion 22
-        versionCode 82
-        versionName "0.6.3.5"
+        versionCode 83
+        versionName "0.6.4.0"
     }
     lintOptions {
         abortOnError false

+ 9 - 17
sample/src/main/java/com/afollestad/materialdialogssample/MainActivity.java

@@ -16,11 +16,9 @@ import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.webkit.WebView;
-import android.widget.AdapterView;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.EditText;
-import android.widget.ListView;
 import android.widget.Toast;
 
 import com.afollestad.materialdialogs.DialogAction;
@@ -354,22 +352,16 @@ public class MainActivity extends ActionBarActivity implements FolderSelectorDia
     }
 
     private void showCustomList() {
-        MaterialDialog dialog = new MaterialDialog.Builder(this)
+        new MaterialDialog.Builder(this)
                 .title(R.string.socialNetworks)
-                .adapter(new ButtonItemAdapter(this, R.array.socialNetworks))
-                .build();
-
-        ListView listView = dialog.getListView();
-        if (listView != null) {
-            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-                @Override
-                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                    Toast.makeText(MainActivity.this, "Clicked item " + position, Toast.LENGTH_SHORT).show();
-                }
-            });
-        }
-
-        dialog.show();
+                .adapter(new ButtonItemAdapter(this, R.array.socialNetworks),
+                        new MaterialDialog.ListCallback() {
+                            @Override
+                            public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) {
+                                Toast.makeText(MainActivity.this, "Clicked item " + which, Toast.LENGTH_SHORT).show();
+                            }
+                        })
+                .show();
     }