【问题标题】:How can I get an event in Android Spinner when the current selected item is selected again?再次选择当前选定的项目时,如何在 Android Spinner 中获取事件?
【发布时间】:2011-07-17 03:47:48
【问题描述】:

我已经为微调器编写了一个 setOnItemSelectedListener 以在微调器项目更改时做出响应。我的要求是当我再次单击当前选定的项目时,应该显示一个 toast。如何获得这个活动?再次单击当前选定的项目时,微调器没有响应。 `

    StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){

        @Override
        public void onItemSelected(AdapterView adapter, View v, int i, long lng) {              
            Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();

        }

        @Override
        public void onNothingSelected(AdapterView arg0) {
            Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();

        }
    });  

【问题讨论】:

    标签: android


    【解决方案1】:

    我花了好几个小时试图解决这个问题。我结束了以下。我不确定它是否适用于所有情况,但它似乎对我有用。它只是 Spinner 类的扩展,它检查选择并在选择设置为相同值时调用侦听器。

    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.Spinner;
    
    
    /** Spinner extension that calls onItemSelected even when the selection is the same as its previous value */
    public class NDSpinner extends Spinner {
    
        public NDSpinner(Context context)
        { super(context); }
    
        public NDSpinner(Context context, AttributeSet attrs)
        { super(context, attrs); }
    
        public NDSpinner(Context context, AttributeSet attrs, int defStyle)
        { super(context, attrs, defStyle); }
    
        @Override 
        public void setSelection(int position, boolean animate) {
            boolean sameSelected = position == getSelectedItemPosition();
            super.setSelection(position, animate);
            if (sameSelected) {
                // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
                getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
            }
        } 
    
        @Override
        public void setSelection(int position) {
            boolean sameSelected = position == getSelectedItemPosition();
            super.setSelection(position);
            if (sameSelected) {
                // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
                getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
            }
        }
    
    }
    

    【讨论】:

    • 非常好的答案,如果有人想在 xml 中使用它,请在 xml 标签中提供完整路径,您将获得相同的功能。
    • 请注意使用“setSelection(int position)”,它是 Spinner.java 类的一部分,一个公共 API。 "setSelection(int position, boolean animate)" 是 AbsSpinner 的一部分,对我来说,在 JB 平台上没有被调用。
    • 让我知道如何在我的活动中使用它
    • 问题是一样的,对我不起作用,如果项目已经被选中,则不会再次被选中
    • 谢谢,效果很好。只是不要忘记在这里尝试捕获 NullPointer:getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
    【解决方案2】:

    试试这个

    public class MySpinner extends Spinner{
    
    OnItemSelectedListener listener;
    
        public MySpinner(Context context, AttributeSet attrs)
        {
            super(context, attrs);
        }
    
        @Override
        public void setSelection(int position)
        {
            super.setSelection(position);
    
            if (position == getSelectedItemPosition())
            {
                listener.onItemSelected(null, null, position, 0);
            }       
        }
    
        public void setOnItemSelectedListener(OnItemSelectedListener listener)
        {
            this.listener = listener;
        }
    }
    

    【讨论】:

    • 效果很好,但一个问题是父视图和视图(前 2 个参数)为空。
    • 我无法渲染这个。这需要自定义 xml 样式吗?我不需要在我的微调器上添加任何新属性,只需添加侦听器功能即可。谢谢!
    • 你能告诉我如何在活动中调用这个扩展类吗?因为我在 setOnItemSelectedListener 中调用了它,它在“listener.onItemSelected(null, null, position, 0);”中给了我运行时 NullPointerException行
    • 我有同样的问题如何在我的活动中调用 MySpinner 类?
    • 参考stackoverflow.com/a/58090975/7392507,以防您想知道如何在 xml 中调用此类以及您的活动类。
    【解决方案3】:

    此微调器将始终告诉您选择已更改:

    package com.mitosoft.ui.widgets;
    
    import java.lang.reflect.Method;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.widget.AdapterView;
    import android.widget.Spinner;
    
    //com.mitosoft.ui.widgets.NoDefaultSpinner
    public class NoDefaultSpinner extends Spinner {
    
        private int lastSelected = 0;
        private static Method s_pSelectionChangedMethod = null;
    
    
        static {        
            try {
                Class noparams[] = {};
                Class targetClass = AdapterView.class;
    
                s_pSelectionChangedMethod = targetClass.getDeclaredMethod("selectionChanged", noparams);            
                if (s_pSelectionChangedMethod != null) {
                    s_pSelectionChangedMethod.setAccessible(true);              
                }
    
            } catch( Exception e ) {
                Log.e("Custom spinner, reflection bug:", e.getMessage());
                throw new RuntimeException(e);
            }
        }
    
        public NoDefaultSpinner(Context context) {
            super(context);
        }
    
        public NoDefaultSpinner(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public NoDefaultSpinner(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public void testReflectionForSelectionChanged() {
            try {
                Class noparams[] = {};          
                s_pSelectionChangedMethod.invoke(this, noparams);
            } catch (Exception e) {
                Log.e("Custom spinner, reflection bug: ", e.getMessage());
                e.printStackTrace();                
            }
        } 
    
    
    
    
        @Override
        public void onClick(DialogInterface dialog, int which) {    
            super.onClick(dialog, which);
                if(lastSelected == which)
                    testReflectionForSelectionChanged();
    
                lastSelected = which;
        }
    }
    

    【讨论】:

    • 在最新的 android 版本上不起作用,永远不会调用 onclick。
    【解决方案4】:

    我想我会为那些使用较新 Android 版本的人留下一个更新的答案。

    我根据上述答案编译了一个函数,该函数至少适用于 4.1.2 和 4.3(我测试过的设备)。此函数不使用反射,而是跟踪最后选择的索引本身,因此即使 SDK 更改了类相互扩展的方式,也应该可以安全使用。

    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.Spinner;
    
    public class SelectAgainSpinner extends Spinner {
    
        private int lastSelected = 0;
    
        public SelectAgainSpinner(Context context)
        { super(context); }
    
        public SelectAgainSpinner(Context context, AttributeSet attrs)
        { super(context, attrs); }
    
        public SelectAgainSpinner(Context context, AttributeSet attrs, int defStyle)
        { super(context, attrs, defStyle); }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            if(this.lastSelected == this.getSelectedItemPosition() && getOnItemSelectedListener() != null)
                getOnItemSelectedListener().onItemSelected(this, getSelectedView(), this.getSelectedItemPosition(), getSelectedItemId());
            if(!changed)
                lastSelected = this.getSelectedItemPosition();
    
            super.onLayout(changed, l, t, r, b);
        } 
    }
    

    【讨论】:

    • 这对我来说比所有答案都有效,谢谢:)
    【解决方案5】:

    kotlin,希望对你有帮助

    import android.content.Context
    import android.util.AttributeSet
    import androidx.appcompat.widget.AppCompatSpinner
    
    class MoreSpinner : AppCompatSpinner {
    
        constructor(context: Context) : super(context)
        constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
        constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    
        override fun setSelection(position: Int, animate: Boolean) {
            val sameSelected = position == selectedItemPosition
            super.setSelection(position, animate)
            if (sameSelected) {
                onItemSelectedListener?.onItemSelected(
                    this,
                    selectedView,
                    position,
                    selectedItemId
                )
            }
        }
    
        override fun setSelection(position: Int) {
            val sameSelected = position == selectedItemPosition
            super.setSelection(position)
            if (sameSelected) {
                onItemSelectedListener?.onItemSelected(
                    this,
                    selectedView,
                    position,
                    selectedItemId
                )
            }
        }
    }
    

    【讨论】:

    • 就是这样。谢谢!
    【解决方案6】:

    对于较新的平台,请尝试将此添加到 Dimitar 的解决方案中。我认为它有效:)

    (你必须重写 onLayout 并移除 onClick 方法)

        @Override
    public void onClick(DialogInterface dialog, int which) {    
        super.onClick(dialog, which);
    }
    
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if(this.lastSelected == this.getSelectedItemPosition())
            testReflectionForSelectionChanged();
        if(!changed)
            lastSelected = this.getSelectedItemPosition();
    
        super.onLayout(changed, l, t, r, b);
    } 
    

    【讨论】:

      【解决方案7】:

      我发现,如果在微调器中再次选择相同的项目,则不会调用 OnItemSelectedListener。当我单击微调器并再次选择相同的值时,不会调用 OnItemSelectedListener 方法。如果根据 UI 设计单击已经处于活动状态的选择,人们不会期望发生任何事情。

      【讨论】:

      • 我同意。用户不期望这种行为。如果您真的需要它,我建议您将微调器子类化并以这种方式绕过它。
      【解决方案8】:

      @Dimitar。哇,出色的工作。感谢那。我不能支持您的解决方案(分数不够),但 NoDefaultSpinner 类有效。只有这一件事是一个问题:因为您在“OnClick”中调用 super.onClick 然后 testReflectionForSelectionChanged(),如果选择确实发生了变化,您将获得微调器的 onItemSelected 处理程序被调用两次(而功能是正确的,如果相同项目被重新选择)。我通过破解它解决了这个问题。我添加了一个 onTouchEvent 覆盖,记录了哪个项目被触摸,然后检查它是否在“onClick”中发生了变化:

      private Object ob=null; //class level variable
       @Override
      public boolean onTouchEvent(MotionEvent m)
      {
          if (m.getAction()==MotionEvent.ACTION_DOWN)
          {
              ob=this.getSelectedItem();
          }
          return super.onTouchEvent(m);
      }
      @Override
      public void onClick(DialogInterface dialog, int which) {    
          super.onClick(dialog, which);
          if (this.getSelectedItem().equals(ob))
              testReflectionForSelectionChanged();
      }
      

      【讨论】:

      • 您可以更轻松地修复它。只需保留最后一个触摸项目的位置变量即可。如果这在下一次点击时相同,则调用 testReflectionForSelectionChanged() 否则不调用。我用这个编辑了 Dimitar 的答案
      • 你能告诉我如何在活动中调用这个扩展类吗?因为我在 setOnItemSelectedListener 中调用了它,它在“listener.onItemSelected(null, null, position, 0);”中给了我运行时 NullPointerException行
      【解决方案9】:

      从这个答案继续https://stackoverflow.com/a/17099104/7392507

      在您的 xml 文件中,创建一个微调器。将微调器标签 <Spinner> 替换为 <yourdomain.yourprojectname.yourpackagename.spinnerclassname>,例如 <com.company.appname.utility.MySpinner>

      在您的 java 文件中,定义 spinner 变量,如下所示: -Spinnerclassname varName = findViewById(R.id.spinnerId);

      例如: -MySpinner varSpinner = findViewById(R.id.spinnerId);

      【讨论】:

        【解决方案10】:

        这不是完整的解决方案,但如果您只想在从任何地方返回片段/活动时调用它,它就可以工作。

        考虑到 mSpinner 是您的 Spinner 视图,我们这样称呼它的监听器:

        @Override public void onResume() {
                if (mSpinner.getCount() > 0) {
                    mSpinner.getOnItemSelectedListener()
                            .onItemSelected( mSpinner, null, mSpinner.getSelectedItemPosition(), 0 );
                }
                super.onResume();
            }
        

        【讨论】:

          【解决方案11】:

          您好,感谢@Dimitar 对这个问题的创造性回答。我已经尝试过了,它在 2.x 等较旧的 Android 版本上运行良好,但不幸的是,它不适用于 3.0 及更高版本(已尝试 3.2 和 4.0.3)。由于某种原因,onClick 方法永远不会在较新的平台上调用。有人在这里写了一个错误报告:http://code.google.com/p/android/issues/detail?id=16245

          无法在较新的平台上运行意味着我需要不同的解决方案。在我的应用程序中,模拟一个未选中的微调器就足够了,并在开始时隐藏了一个“虚拟”条目。然后,如果将“隐藏”项设置为选择项,则单击的每个项都会导致回调。对某些人来说,一个缺点可能是不会显示任何内容,但可以使用 Spinner 类覆盖技巧来解决这个问题。

          How to hide one item in an Android Spinner

          【讨论】:

            【解决方案12】:

            我们的要求不会出现 Spinner 行为。我的解决方案不适用于 Spinners,以一种类似的方式进行,在一个 BaseFragment 中使用一个 ListView 来研究我们所期望的功能。

            好处是:

            1. 扩展 Spinner 默认设置不再令人头疼。
            2. 易于实施和定制。
            3. 完全兼容所有 Android API。
            4. 第一次 OnItemSelectedListener.onItemSelected 调用没有面子。

            主要思想是做这样的事情:

            BaseFragment 布局可能类似于:

            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                          android:background="@null"
                          android:layout_width="match_parent"
                          android:layout_height="match_parent"
                          android:orientation="vertical"
                          android:gravity="center">
            
                <ListView
                        android:id="@+id/fragment_spinnerList"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"/>
            </LinearLayout>
            

            代码如下所示:

            public class SpinnerListFragment extends android.support.v4.app.DialogFragment {
            
                static SpinnerListFragment newInstance(List<String> items) {
            
                    SpinnerListFragment spinnerListFragment = new SpinnerListFragment();
                    Bundle args = new Bundle();
            
                    args.putCharSequenceArrayList("items", (ArrayList) items);
                    spinnerListFragment.setArguments(args);
            
                    return spinnerListFragment;
                }
            
                @Override
                public Dialog onCreateDialog(Bundle savedInstanceState) {
            
                    Dialog dialog = new Dialog(getActivity(), R.style.dialog);
                    final View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_spinner_list, null);
            
                    dialog.getWindow().setContentView(view);
                    dialog.setCanceledOnTouchOutside(true);
            
                    // CUSTOMIZATION...
            
                    final List items = (ArrayList) getArguments().getCharSequenceArrayList("items");
            
                    final ListView spinnerList = (ListView) view.findViewById(R.id.fragment_spinnerList);
            
                    ArrayAdapter<String> arrayAdapter =
                            new ArrayAdapter<String>(
                                    getActivity(),
                                    R.layout.search_spinner_list_item,
                                    items);
            
                    spinnerList.setAdapter(arrayAdapter);
            
                    spinnerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            
                        @Override
                        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            
                            // DO SOMETHING...
            
                            SpinnerListFragment.this.dismiss();
                        }
                    });
            
                    return dialog;
                }
            
            }
            

            【讨论】:

              【解决方案13】:

              我的解决方案是基于 benoffi7 的 MySpinner。通过保存最后选择的父项和视图来修复在同一项目选择上传递空值。

              public class MySpinner extends Spinner {
              
                  private OnItemSelectedListener listener;
                  private AdapterView<?> lastParent;
                  private View lastView;
                  private long lastId;
              
                  public MySpinner(Context context, AttributeSet attrs) {
                      super(context, attrs);
                      initInternalListener();
                  }
              
                  public MySpinner(Context context, AttributeSet attrs, int defStyle) {
                      super(context, attrs, defStyle);
                      initInternalListener();
                  }
              
                  private void initInternalListener() {
                      super.setOnItemSelectedListener(new OnItemSelectedListener() {
              
                          @Override
                          public void onItemSelected(AdapterView<?> parent, View view,
                              int position, long id) {
                              lastParent = parent;
                              lastView = view;
                              lastId = id;
                              if (listener != null) {
                                  listener.onItemSelected(parent, view, position, id);
                              }
                          }
              
                          @Override
                          public void onNothingSelected(AdapterView<?> parent) {
                              //lastParent = parent; // do we need it?
                              if (listener != null) {
                                  listener.onNothingSelected(parent);
                              }
                          }
                      });
                  }
              
                  @Override
                  public void setSelection(int position) {
                      if (position == getSelectedItemPosition() && listener != null) {
                          listener.onItemSelected(lastParent, lastView, position, lastId);
                      } else {
                          super.setSelection(position);
                      }
                  }
              
                  @Override
                  public void setOnItemSelectedListener(OnItemSelectedListener listener) {
                      this.listener = listener;
                  }
              }
              

              【讨论】:

                【解决方案14】:
                class MySpinner extends Spinner {
                
                
                    public MySpinner(Context context) {
                        super(context);
                        // TODO Auto-generated constructor stub
                    }
                    public MySpinner(Context context, AttributeSet attrs)
                    {
                        super(context, attrs);
                    }
                    @Override
                    public void setSelection(int position, boolean animate) {
                        ignoreOldSelectionByReflection();
                        super.setSelection(position, animate);
                    }
                
                    private void ignoreOldSelectionByReflection() {
                        try {
                            Class<?> c = this.getClass().getSuperclass().getSuperclass().getSuperclass();
                            Field reqField = c.getDeclaredField("mOldSelectedPosition");
                            reqField.setAccessible(true);
                            reqField.setInt(this, -1);
                        } catch (Exception e) {
                            Log.d("Exception Private", "ex", e);
                            // TODO: handle exception
                        }
                    }
                
                    @Override
                    public void setSelection(int position) {
                        ignoreOldSelectionByReflection();
                        super.setSelection(position);
                    }
                
                }
                

                【讨论】:

                • 您能解释一下您的答案如何解决 OP 的问题吗?
                • MySpinner 类扩展 Spinner 类时,在回调方法 setSelection(int position) 中调用方法 ignoreOldSelectionByReflection()。在微调器中找到 oldselected 位置并使其可访问并将其设置为 -1 意味着它在内部更改所选位置但用户看不到。因此,当用户在微调器中选择与先前选择的位置相同的位置时,它将不会失败。
                • 请编辑您的答案以添加此信息。这样,您将真正改善您的答案
                • 嗨 Garf365,我试图编辑我的答案,但不幸的是,我遇到了错误,因为 SO 在数据发布中遵循某种格式。谢谢你的好建议。
                • 这个(以及扩展 Spinner 的其他示例)对我不起作用。您是否正在为任何特定的 SDK 构建?我正在为 v11 到 v23 构建...
                【解决方案15】:

                这是一个简单的解决方案,因为可以基于“onTouch”以编程方式设置“选定项”,如下所示:

                spinnerobject.setOnTouchListener(new AdapterView.OnTouchListener() {
                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
                
                            final int MAKE_A_SELECTION = 1; //whatever index that is the normal starting point of the spinner.
                            spinnerObject.setSelection(MAKE_A_SELECTION);
                            return false;
                        }
                    });
                

                有一个微小的损失,即 (1) 微调器文本将在显示微调器行之前更改回默认值,以及 (2) 此默认项将成为列表的一部分。也许有人可以添加如何禁用微调器的特定项目?

                一般来说,由于微调器选择可能会执行可重复的事件(例如开始搜索),因此无法在微调器中重新选择项目实际上是 Spinner 类中缺少的功能/错误,这是 Android 开发人员的错误应该尽快改正。

                【讨论】:

                • 我喜欢这个 carl 的简单性(而且它有效——所有扩展 Spinner 类的例子都不适用于我),但我担心用户会因为你提到的惩罚 1 而烦恼。您是否找到了在屏幕上没有此次要默认“闪光灯”的替代方案?
                • 其实在这个解决方案中发现了一个缺陷。如果您使用设备后退按钮退出微调器视图,微调器将重置为默认项目。
                【解决方案16】:

                嗨,伙计,这对我有用:

                ArrayAdapter<String> adaptador1 = new ArrayAdapter<String>( Ed_Central.this, 
                                                                            android.R.layout.simple_spinner_item,
                                                                            datos1
                                                                            );
                        lista1.setAdapter( adaptador1 );
                
                        lista1.setOnItemSelectedListener( new AdapterView.OnItemSelectedListener() {
                            @Override
                            public void onItemSelected( AdapterView<?> parent, View view, int position, long id ) {
                
                                lista1.setSelection( 0 );
                
                                switch ( position ) {
                                    case 1:
                                        Toast.makeText( getApplicationContext(), "msg1", Toast.LENGTH_SHORT ).show();
                                        break;
                                    case 2:
                                        Toast.makeText( getApplicationContext(), "msg2", Toast.LENGTH_SHORT ).show();
                                        break;
                                    case 3:
                                        Toast.makeText( getApplicationContext(), "msg3", Toast.LENGTH_SHORT ).show();
                                        break;
                
                                    default:
                                        break;
                                }
                            }
                

                适配器始终位于“0”位置,您可以展示您的 toast。

                【讨论】:

                  【解决方案17】:
                  package customclasses;
                  
                  /**
                   * Created by Deepak on 7/1/2015.
                   */
                  
                  import android.content.Context;
                  import android.util.AttributeSet;
                  import android.widget.Spinner;
                  
                  /**
                   * Spinner extension that calls onItemSelected even when the selection is the same as its previous value
                   */
                  public class NDSpinner extends Spinner {
                      public boolean isDropDownMenuShown=false;
                  
                      public NDSpinner(Context context) {
                          super(context);
                      }
                  
                      public NDSpinner(Context context, AttributeSet attrs) {
                          super(context, attrs);
                      }
                  
                      public NDSpinner(Context context, AttributeSet attrs, int defStyle) {
                          super(context, attrs, defStyle);
                      }
                  
                  
                      @Override
                      public void
                      setSelection(int position, boolean animate) {
                          boolean sameSelected = position == getSelectedItemPosition();
                          super.setSelection(position, animate);
                          if (sameSelected) {
                              // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
                              getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
                          }
                      }
                  
                      @Override
                      public boolean performClick() {
                          this.isDropDownMenuShown = true; //Flag to indicate the spinner menu is shown
                          return super.performClick();
                      }
                      public boolean isDropDownMenuShown(){
                          return isDropDownMenuShown;
                      }
                      public void setDropDownMenuShown(boolean isDropDownMenuShown){
                          this.isDropDownMenuShown=isDropDownMenuShown;
                      }
                      @Override
                      public void
                      setSelection(int position) {
                          boolean sameSelected = position == getSelectedItemPosition();
                          super.setSelection(position);
                          if (sameSelected) {
                              // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
                              getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
                          }
                      }
                      @Override
                      public void onDetachedFromWindow() {
                          super.onDetachedFromWindow();
                      }
                  }
                  

                  【讨论】:

                    【解决方案18】:

                    Kotlin 中具有相同项目选择回调的自定义微调器:

                    class StorageSpinner : AppCompatSpinner {
                    
                        constructor(context: Context) : super(context)
                        constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
                        constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
                    
                        interface StorageSpinnerSelectionCallback {
                            fun onItemSelected(position: Int)
                        }
                    
                        private var selectionCallback: StorageSpinnerSelectionCallback? = null
                    
                        fun setSelectionCallback(selectionCallback: StorageSpinnerSelectionCallback) {
                            this.selectionCallback = selectionCallback
                        }
                    
                        fun removeSelectionCallback() {
                            selectionCallback = null
                        }
                    
                        override fun setSelection(position: Int) {
                            super.setSelection(position)
                    
                            if (position == selectedItemPosition) selectionCallback?.onItemSelected(position)
                        }
                    }
                    

                    【讨论】:

                      【解决方案19】:

                      试试这个,这可能不是正确的解决方案,但如果不制作自定义微调器,这可能是目前可用的最佳解决方案。

                      您要做的是在每次点击项目时重置微调器适配器,

                       @Override
                          public void onItemSelected(AdapterView adapter, View v, int position, long lng) {              
                      
                          if (position == getSelectedItemPosition())
                          {
                              //do your thing
                              //then at end of statement reset adapter like
                      
                             spinner.setAdapter(adapter);
                          } 
                      
                          }
                      

                      希望能帮到你解决问题

                      【讨论】:

                        【解决方案20】:

                        如果您真的想在您的 XML 中执行此任务,当您的微调器显示添加一个编辑文本并设置可见性消失属性时;并为微调器创建服装适配器,并在 view.onclicklisner 上设置的服装适配器以及 clickevent 触发 EditText.setText("0");并在活动集 edittext textWatcher 事件和事件块中添加您的 onSpinerItem 事件块代码;你的问题解决了

                        【讨论】:

                          【解决方案21】:

                          您必须执行以下步骤: 1.为微调器创建一个适配器客户 2.在override fun getDropDownView(...)中,必须放一个view.setOnClickListener {"interface"} 3. 创建界面

                          【讨论】:

                          • 多解释一点也无妨
                          【解决方案22】:

                          无需扩展微调器。 我以下列方式使用 SpinnerAdapter:

                              public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle  savedInstanceState) {
                              //....
                              //Create an ArrayAdapter as usual
                              myArrayAdapter = new ArrayAdapter(mParentView.getContext(),R.layout.myarrayadapter_item);
                              //Create a Spinner as usual
                              mySpinner = (Spinner)mParentView.findViewById(R.id.myspinner);
                          
                              //create a spinneradapter
                              //selecting the same item twice will not throw an onselectionchange event
                              //therefore add an OnTouchlistener to the DropDownView items
                              SpinnerAdapter o_SpinnerAdapter = new SpinnerAdapter() {
                                      private ArrayAdapter m_ArrayAdapter = myArrayAdapter;
                                      private View.OnTouchListener m_OnTouchListener = new View.OnTouchListener() {
                                      @Override
                                      public boolean onTouch(View v, MotionEvent event) {
                                              //do something
                                             return false; //return false, don't consume the event
                                      };
                                      @Override
                                      public View getDropDownView(int position, View convertView, ViewGroup parent) {
                                              TextView o_TextView; //usual the view is a TextView
                                              o_TextView = (TextView)m_ArrayAdapter.getView(position,convertView,parent);
                                              o_TextView.setOnTouchListener(m_OnTouchListener); //Add the ontouchlistener
                                              return o_TextView;
                                      }
                          
                                      @Override
                                      public void registerDataSetObserver(DataSetObserver observer) {
                                              m_ArrayAdapter.registerDataSetObserver(observer);
                                      }
                                      @Override
                                      public void unregisterDataSetObserver(DataSetObserver observer) {
                                              m_ArrayAdapter.unregisterDataSetObserver(observer);
                                      }
                                      @Override
                                      public int getCount() {
                                              return m_ArrayAdapter.getCount();
                                      }
                                      @Override
                                      public Object getItem(int position) {
                                              return m_ArrayAdapter.getItem(position);
                                      }
                                      @Override
                                      public long getItemId(int position) {
                                              return m_ArrayAdapter.getItemId(position);
                                      }
                                      @Override
                                      public boolean hasStableIds() {
                                              return m_ArrayAdapter.hasStableIds();
                                      }
                                      @Override
                                      public View getView(int position, View convertView, ViewGroup parent) {
                                              return m_ArrayAdapter.getView(position, convertView, parent);
                                      }
                                      @Override
                                      public int getItemViewType(int position) {
                                              return m_ArrayAdapter.getItemViewType(position);
                                      }
                                      @Override
                                      public int getViewTypeCount() {
                                              return m_ArrayAdapter.getViewTypeCount();
                                      }
                                      @Override
                                      public boolean isEmpty() {
                                              return m_ArrayAdapter.isEmpty();
                                      }
                              };
                              //Set the SpinnerAdapter instead of myArrayAdapter
                              m_SpinnerDMXDeviceGroups.setAdapter(o_SpinnerAdapter);
                          
                              //.......
                              }
                          

                          希望对你有帮助

                          【讨论】:

                            【解决方案23】:

                            试试这个。

                            @Override
                            public void onItemSelected(AdapterView adapter, View v, int i, long lng) {  
                            
                                if(v.hasFocus() {            
                                    Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
                                }    
                            }
                            

                            希望它可以工作。

                            【讨论】:

                            • toast 消息未显示
                            • 为此也提供一个 else 。 Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getLastVisiblePosition(), Toast.LENGTH_SHORT).show();试试这个看看。
                            • toast 消息在 else 条件下打印。问题是当我再次选择当前选择的项目时,没有 toast 消息。
                            • no.. itz 不工作 :(。吐司在第一次显示。当我再次选择相同的项目时,没有吐司。
                            【解决方案24】:

                            当您再次单击当前选定的项目时,它不会触发任何事件。因此,您无法捕获 setOnItemSelectedListener 以使微调器响应。

                            【讨论】:

                            • 你可以做到,只需制作一个自定义微调器并按照 Dimitar 的回答
                            • 为什么这个答案被标记为正确答案?还有+50???我认为它对解决问题没有任何帮助!如果我错了,有人纠正我。
                            • 我也有同样的问题。为什么+50就可以了。问:我怎样才能让它工作。 A:目前无法使用。 Bweeee。
                            • 这不是@indira 想要的答案。告诉一个方法如何实现这一点。
                            • 我觉得这种情况令人费解。
                            猜你喜欢
                            • 1970-01-01
                            • 2017-07-19
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2016-09-18
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多