【问题标题】:How do I create an Android Spinner as a popup?如何将 Android Spinner 创建为弹出窗口?
【发布时间】:2011-09-11 07:48:48
【问题描述】:

当用户点击菜单项以允许用户选择项目时,我想调出一个微调对话框。

我需要一个单独的对话框,还是可以直接使用 Spinner?我看到this link, 提到了一个 MODE_DIALOG 选项,但它似乎不再被定义。 AlertDialog 可能没问题,但所有选项都说“单击列表中的项目不会关闭对话框”,这正是我想要的。有什么建议吗?

理想情况下,代码类似于屏幕上显示微调器的情况:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity,
     android.R.layout.simple_spinner_item, items);              
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
myspinner.setAdapter(adapter);  
// myspinner.showAsDialog() <-- what i want             

【问题讨论】:

    标签: android dialog spinner


    【解决方案1】:

    您可以使用警告对话框

        AlertDialog.Builder b = new Builder(this);
        b.setTitle("Example");
        String[] types = {"By Zip", "By Category"};
        b.setItems(types, new OnClickListener() {
    
            @Override
            public void onClick(DialogInterface dialog, int which) {
    
                dialog.dismiss();
                switch(which){
                case 0:
                    onZipRequested();
                    break;
                case 1:
                    onCategoryRequested();
                    break;
                }
            }
    
        });
    
        b.show();
    

    当您想要按下其中一个时,这将关闭对话框。希望这会有所帮助!

    【讨论】:

    • 谢谢!如何设置最初选择的单选按钮之一? (我正在使用它让用户选择一个值,但已经有一个当前值,因此应该指出。)
    • 使用 setSingleChoiceItems() 代替 int 参数来表示首先选择哪个项目。
    • 这段代码有错误,其中之一是The method onClick(DialogInterface, int) of type new View.OnClickListener(){} must override or implement a supertype method
    • 啊,没关系,它引用了不同的 OnClickListener。不得不改用new DialogInterface.OnclickListener...
    • 哇,我不知道你能做到这一点 :) 我使用了 setItems(@ArrayRes) 函数,如果你有一些不会改变的选项,这个函数很有用
    【解决方案2】:

    xml中有选项

    android:spinnerMode="dialog"
    

    将此用于对话模式

    【讨论】:

      【解决方案3】:

      试试这个:

      Spinner popupSpinner = new Spinner(context, Spinner.MODE_DIALOG);
      

      查看link了解更多详情。

      【讨论】:

        【解决方案4】:

        MODE_DIALOGMODE_DROPDOWN 在 API 11 (Honeycomb) 中定义。 MODE_DIALOG 描述了以前平台版本中的常见行为。

        【讨论】:

        • 啊,API 11。这解释了那部分。谢谢!
        【解决方案5】:

        添加一个小属性为android:spinnerMode="dialog" 将在弹出窗口中显示微调器内容。

        【讨论】:

          【解决方案6】:

          您可以创建自己的自定义对话框。这很容易。如果您想通过微调器中的选择来关闭它,请添加 OnItemClickListener 并添加

          int n = mSpinner.getSelectedItemPosition();
          mReadyListener.ready(n);
          SpinnerDialog.this.dismiss();
          

          就像在 OK 按钮的 OnClickListener 中一样。但是,有一个警告,如果您重新选择默认选项,onclick 侦听器不会触发。您还需要确定按钮。

          从布局开始:

          res/layout/spinner_dialog.xml

          <?xml version="1.0" encoding="utf-8"?>
          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content">
          <TextView 
              android:id="@+id/dialog_label" 
              android:layout_height="wrap_content" 
              android:layout_width="fill_parent"
              android:hint="Please select an option" 
              />
          <Spinner
              android:id="@+id/dialog_spinner" 
              android:layout_height="wrap_content" 
              android:layout_width="fill_parent"
              />
          <Button
              android:id="@+id/dialogOK" 
              android:layout_width="120dp"
              android:layout_height="wrap_content" 
              android:text="OK"
              android:layout_below="@id/dialog_spinner"
              />
          <Button
              android:id="@+id/dialogCancel" 
              android:layout_width="120dp"
              android:layout_height="wrap_content" 
              android:text="Cancel"
              android:layout_below="@id/dialog_spinner"
              android:layout_toRightOf="@id/dialogOK"
              />
          </RelativeLayout>
          

          然后,创建类:

          src/your/package/SpinnerDialog.java

          public class SpinnerDialog extends Dialog {
              private ArrayList<String> mList;
              private Context mContext;
              private Spinner mSpinner;
          
             public interface DialogListener {
                  public void ready(int n);
                  public void cancelled();
              }
          
              private DialogListener mReadyListener;
          
              public SpinnerDialog(Context context, ArrayList<String> list, DialogListener readyListener) {
                  super(context);
                  mReadyListener = readyListener;
                  mContext = context;
                  mList = new ArrayList<String>();
                  mList = list;
              }
          
              @Override
              public void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
          
                  setContentView(R.layout.spinner_dialog);
                  mSpinner = (Spinner) findViewById (R.id.dialog_spinner);
                  ArrayAdapter<String> adapter = new ArrayAdapter<String> (mContext, android.R.layout.simple_spinner_dropdown_item, mList);
                  mSpinner.setAdapter(adapter);
          
                  Button buttonOK = (Button) findViewById(R.id.dialogOK);
                  Button buttonCancel = (Button) findViewById(R.id.dialogCancel);
                  buttonOK.setOnClickListener(new android.view.View.OnClickListener(){
                      public void onClick(View v) {
                          int n = mSpinner.getSelectedItemPosition();
                          mReadyListener.ready(n);
                          SpinnerDialog.this.dismiss();
                      }
                  });
                  buttonCancel.setOnClickListener(new android.view.View.OnClickListener(){
                      public void onClick(View v) {
                          mReadyListener.cancelled();
                          SpinnerDialog.this.dismiss();
                      }
                  });
              }
          }
          

          最后,将其用作:

          mSpinnerDialog = new SpinnerDialog(this, mTimers, new SpinnerDialog.DialogListener() {
            public void cancelled() {
              // do your code here
            }
            public void ready(int n) {
              // do your code here
            }
          });
          

          【讨论】:

          • 谢谢,但这不会创建一个带有微调器小部件的对话框,然后用户需要再次单击微调器才能获得对话框?我在stackoverflow.com/questions/867518/… 找到了答案。请参阅 HRJ 的回答。
          • @Edwin,我对你的评论感到迷茫。这将在那里创建一个带有微调器的对话框。是的,用户需要单击微调器来选择项目,但这就是微调器的工作方式。然后,单击 OK 按钮(或者,如果您像上面一样添加 onclicklistener,只需选择一个项目),将返回所选项目索引并关闭对话框。如果这不是你需要的,那么我不知道你在问什么。
          • 哈哈,太好了,我想知道,有时我开始回答一些问题,然后意识到正确地回答可能会花费更多的时间而不是值得的,但是把它安排好当然很好给你。
          • @Aleadam。我编辑了这个问题,现在更清楚了。我希望它直接转到用户单击处于折叠状态的微调器后出现的 UI。
          • @Aleadam 在类定义中的“DeleteDialog”方法名称实际上应该是“SpinnerDialog”。同样在使用示例中,它应该实例化“SpinnerDialog.DialogListener”而不是错误的“SpinnerDialog.SpinnerListener”。
          【解决方案7】:
          android:spinnerMode="dialog"
          
          // Creating adapter for spinner
          
          ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, categories);
          
          // Drop down layout style - list view with radio button
          dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
          
          // attaching data adapter to spinner
          spinner.setAdapter(dataAdapter);
          

          【讨论】:

            【解决方案8】:

            您可以使用微调器并将 spinnerMode 设置为对话框,并将 layout_width 和 layout_height 设置为 0,以便主视图不显示,仅显示对话框(下拉视图)。在按钮点击监听器中调用 performClick。

                mButtonAdd.setOnClickListener(view -> {
                    spinnerAddToList.performClick();
                });
            

            布局:

                <Spinner
                    android:id="@+id/spinnerAddToList"
                    android:layout_width="0dp"
                    android:layout_height="0dp"
                    android:layout_marginTop="10dp"
                    android:prompt="@string/select_from_list"
                    android:theme="@style/ThemeOverlay.AppCompat.Light"
                    android:spinnerMode="dialog"/>
            

            这样做的好处是您可以随心所欲地自定义微调器。

            在此处查看我的答案以自定义微调器: Overriding dropdown list style for Spinner in Dialog mode

            【讨论】:

              【解决方案9】:

              这是一个 Spinner 子类,它覆盖 performClick() 以显示对话框而不是下拉菜单。不需要 XML。试试看,让我知道它是否适合你。

              public class DialogSpinner extends Spinner {
                  public DialogSpinner(Context context) {
                      super(context);
                  }
              
                  @Override 
                  public boolean performClick() {
                      new AlertDialog.Builder(getContext()).setAdapter((ListAdapter) getAdapter(), 
                          new DialogInterface.OnClickListener() {
                              @Override public void onClick(DialogInterface dialog, int which) {
                                  setSelection(which);
                                  dialog.dismiss();
                              }
                          }).create().show();
                      return true;
                  }
              }
              

              更多信息请阅读这篇文章:How To Make Android Spinner Options Popup In A Dialog

              【讨论】:

                【解决方案10】:

                这是来自 Android SDK 源代码。 如您所见,您有一个特殊的构造函数来创建具有您想要使用的指定模式的 Spinner。

                希望对你有帮助:)

                 /**
                     * Construct a new spinner with the given context's theme, the supplied attribute set,
                     * and default style. <code>mode</code> may be one of {@link #MODE_DIALOG} or
                     * {@link #MODE_DROPDOWN} and determines how the user will select choices from the spinner.
                     *
                     * @param context The Context the view is running in, through which it can
                     *        access the current theme, resources, etc.
                     * @param attrs The attributes of the XML tag that is inflating the view.
                     * @param defStyle The default style to apply to this view. If 0, no style
                     *        will be applied (beyond what is included in the theme). This may
                     *        either be an attribute resource, whose value will be retrieved
                     *        from the current theme, or an explicit style resource.
                     * @param mode Constant describing how the user will select choices from the spinner.
                     * 
                     * @see #MODE_DIALOG
                     * @see #MODE_DROPDOWN
                     */
                    public Spinner(Context context, AttributeSet attrs, int defStyle, int mode) {
                        super(context, attrs, defStyle);
                

                【讨论】:

                  【解决方案11】:

                  如果您想将其显示为全屏弹出窗口,那么您甚至不需要 xml 布局。以下是在 Kotlin 中的操作方法。

                   val inputArray: Array<String> = arrayOf("Item 1","Item 2")
                                  val alt_bld =  AlertDialog.Builder(context);
                                  alt_bld.setTitle("Items:")
                                  alt_bld.setSingleChoiceItems(inputArray, -1) { dialog, which ->
                                      if(which == 0){
                                          //Item 1 Selected
                                      }
                                      else if(which == 1){
                                          //Item 2 Selected
                                      }
                                      dialog.dismiss();
                  
                                  }
                  
                                  val alert11 = alt_bld.create()
                                  alert11.show()
                  

                  【讨论】:

                    【解决方案12】:

                    这是基于已接受答案的 Kotlin 版本

                    每次单击按钮时,我都会从适配器使用此对话框。

                    yourButton.setOnClickListener {
                        showDialog(it /*here I pass additional arguments*/)
                    }
                    

                    为了防止双击我立即禁用按钮,并在执行/取消操作后重新启用。

                    private fun showDialog(view: View /*additional parameters*/) {
                        view.isEnabled = false
                    
                        val builder = AlertDialog.Builder(context)
                        builder.setTitle(R.string.your_dialog_title)
                    
                        val options = arrayOf("Option A", "Option B")
                    
                        builder.setItems(options) { dialog, which ->
                            dialog.dismiss()
                    
                            when (which) {
                                /* execute here your actions */
                                0 -> context.toast("Selected option A")
                                1 -> context.toast("Selected option B")
                            }
                    
                            view.isEnabled = true
                        }
                    
                        builder.setOnCancelListener {
                            view.isEnabled = true
                        }
                    
                        builder.show()
                    }
                    

                    如果您在 Activity 中使用它,则可以使用 this 而不是 context 变量。

                    【讨论】:

                      猜你喜欢
                      • 2014-05-26
                      • 1970-01-01
                      • 1970-01-01
                      • 2017-08-28
                      • 2011-12-16
                      • 2021-10-07
                      • 2018-02-10
                      • 2014-04-18
                      相关资源
                      最近更新 更多