Android Spinner OnItemSelected不会在选择相同的项目时被调用

13

首先,我知道这个问题已经被问了很多次,但在新版本的Android上,似乎建议的解决方案不起作用。 我需要让我的Spinner即使用户两次选择同一个项目也能调用OnItemSelected。 我找到了这个类,它应该能解决问题:

    public class NDSpinner 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 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
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);
} 



    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);
    }
}

这实际上是可行的,但存在一个bug:第一次调用两次该项 :( 有人能告诉我如何解决这个问题吗?

谢谢大家。


更好的实现方式 - https://dev59.com/8Ggv5IYBdhLWcg3wF85P#62894086 - Vishal Yadav
2个回答

30

我使用了这个类来解决问题:

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());
        }
      }
    }

不管怎样,还是谢谢您 :)


经过几个小时的研究,终于找到了你的答案。你节省了我很多时间。谢谢,伙计。 - Hesam
我该如何在我的活动中使用这个? - Hammad Nasir
@HammadNasir 这只是一个自定义的Spinner。只需使用NDSpinner对象而不是经典的Spinner即可。 - Luca D'Amico
boolean sameSelected = position == getSelectedItemPosition(); 始终为TRUE,getSelectedItemPosition()方法返回的值与position相同,请查看我的帖子-https://dev59.com/8Ggv5IYBdhLWcg3wF85P#62894086 - Vishal Yadav

0
对于我来说,我扩展了AppCompatSpinner。
另外,如果你的Spinner是在XML中布局的,请记得更改它。
<Spinner...

<com.example.util.NDSpinner...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接