关于Spinner点击同一条目不回调OnItemSelectedListener的解决办法

最近使用Spinner时,发现点击同一条目便不再回调OnItemSelectedListener,很多文章解释的很好,但是给出的解决办法有些是有Bug的,我这里整理两种亲测有效的解决办法,直接加到代码里面就能用。

方法一

给Spinner多加一个回调,每次选择后,重置里面的mOldSelectedPosition属性值

spinner.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {

            @Override
            public void onChildViewAdded(View parent, View child) {
                log.info("onChildViewAdded--------------");
            }

            @Override
            public void onChildViewRemoved(View parent, View child) {
                log.info("onChildViewRemoved--------------");
                try {
                    Class<?> clazz = AdapterView.class;
                    Field mOldSelectedPosition = clazz.getDeclaredField("mOldSelectedPosition");
                    mOldSelectedPosition.setAccessible(true);
                    mOldSelectedPosition.setInt(services_spinner,AdapterView.INVALID_POSITION);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

方法二

自定义一个类,继承Spinner,当选中同一条目时,手动触发OnItemSelectedListener的onItemSelected()方法,使用时直接在XML布局里面使用这个类就可以

package com.demo.xxx;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Spinner;

@SuppressLint("AppCompatCustomView")
public class ReSpinner extends Spinner {
    public boolean isDropDownMenuShown = false;//标志下拉列表是否正在显示

    public ReSpinner(Context context) {
        super(context);
    }

    public ReSpinner(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ReSpinner(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 && getOnItemSelectedListener() != null) {
            // 如果选择项是Spinner当前已选择的项,则 OnItemSelectedListener并不会触发,因此这里手动触发回调
            getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
        }
    }

    @Override
    public boolean performClick() {
        this.isDropDownMenuShown = true;
        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 && getOnItemSelectedListener() != null) {
            getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
        }
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
    }
}

推荐使用第二种解决办法,适合项目中有多个Spinner的情况,第一种解决办法适合处理其中某一个Spinner有这个需求的情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值