Android中使用Spinner有时有二级菜单需要操作,这时选中了某一项,想再点击这一项进入二级菜单重新选择时,onItemSelected方法是不会重新调用的,二级菜单出不来,影响功能。看Spinner源码,只有现在选中的position(或rowId)和点击的position(或rowId)不一样,才会触发onItemSelected回调。

AdapterView.java:

void checkSelectionChanged() {        if ((mSelectedPosition != mOldSelectedPosition) || (mSelectedRowId != mOldSelectedRowId)) {            selectionChanged();            mOldSelectedPosition = mSelectedPosition;            mOldSelectedRowId = mSelectedRowId;        }}void selectionChanged() {        if (mOnItemSelectedListener != null                || AccessibilityManager.getInstance(mContext).isEnabled()) {            if (mInLayout || mBlockLayoutRequests) {                // If we are in a layout traversal, defer notification                // by posting. This ensures that the view tree is                // in a consistent state and is able to accomodate                // new layout or invalidate requests.                if (mSelectionNotifier == null) {                    mSelectionNotifier = new SelectionNotifier();                }                post(mSelectionNotifier);            } else {                fireOnSelected();                performAccessibilityActionsOnSelected();            }        }    }private void fireOnSelected() {        if (mOnItemSelectedListener == null) {            return;        }        final int selection = getSelectedItemPosition();        if (selection >= 0) {            View v = getSelectedView();            mOnItemSelectedListener.onItemSelected(this, v, selection,                    getAdapter().getItemId(selection));        } else {            mOnItemSelectedListener.onNothingSelected(this);        }    }

那么方案就是让点击的position(或mSelectedRowId )和之前的position(或mSelectedRowId )不一样即可让回调方法执行。那么拦截onTouch事件,在其中将mOldSelectedPositionmOldSelectedRowId改为不会和现在点击的一样即可。方法如下:

spinner.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                try {                    Class<?> clazz = AdapterView.class;                    //Field field = clazz.getDeclaredField("mOldSelectedPosition");                    //field.setAccessible(true);                    //field.setInt(spn,-1);                    Field field = clazz.getDeclaredField("mOldSelectedRowId");                    field.setAccessible(true);                    field.setInt(spn_ps,Integer.MIN_VALUE);                } catch(Exception e){                    e.printStackTrace();                }                return false;            }        });

onTouch返回false,这样事件可以继续传递下去,OnItemSelectedListener得以响应。

更多相关文章

  1. [转]Android(安卓)ORM系列之GreenDao最佳实践
  2. 由Android(安卓)65K方法数限制引发的思考
  3. Google android初级开发之 : android 编译环境安装(for ubuntu9.
  4. 《Android(安卓)Dev Guide》系列教程17:建立自定义View组件
  5. Android实现类似excel表格的方法整理
  6. 【Android性能优化】使用NDK进行Java和C++混编
  7. 一文彻底搞懂Android(安卓)View的绘制流程
  8. Android(安卓)Audio底层原理(一)
  9. Android研究院之应用程序ListView 详解 (六)

随机推荐

  1. 生成Android(安卓)App签名(为APK签名)
  2. 什么是Android------Android中文SDK
  3. 【Android Dev Guide - 02】 - Applicati
  4. 极光推送获取不到RegisterId(注册ID)Andr
  5. Android中给Listview的HeadView加ViewPag
  6. Flutter底部导航栏NavigationBar的几种实
  7. Android 获取系统音量
  8. COCOS2D-X编译成android的项目
  9. Android: Unknown “Bitmap” cause by '
  10. Android 之 拦截手机短信并自动转发