如何实现Android Spinner同已选选项重选的事件触发功能
问题根因
Android 原生Spinner默认仅在新选中条目位置与当前已选中位置不一致时,才会触发OnItemSelectedListener的onItemSelected回调,这是你重复选中同一位置条目无法触发API调用的核心原因。
解决方法
通过自定义Spinner强制同位置选中也触发回调,实现步骤如下:
1. 新建自定义Spinner类
import android.content.Context; import android.util.AttributeSet; import android.widget.AdapterView; import android.widget.Spinner; public class ReSelectableSpinner extends Spinner { public ReSelectableSpinner(Context context) { super(context); } public ReSelectableSpinner(Context context, AttributeSet attrs) { super(context, attrs); } public ReSelectableSpinner(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void setSelection(int position, boolean animate) { super.setSelection(position, animate); AdapterView.OnItemSelectedListener listener = getOnItemSelectedListener(); if (listener != null && position == getSelectedItemPosition()) { listener.onItemSelected(this, getSelectedView(), position, getSelectedItemId()); } } @Override public void setSelection(int position) { super.setSelection(position); AdapterView.OnItemSelectedListener listener = getOnItemSelectedListener(); if (listener != null && position == getSelectedItemPosition()) { listener.onItemSelected(this, getSelectedView(), position, getSelectedItemId()); } } }
2. 替换布局文件中的Spinner
将布局中原有的<Spinner>标签替换为自定义的ReSelectableSpinner,需填写你项目中该类的完整包名:
<!-- 替换为你实际的包名 --> <com.your.package.name.ReSelectableSpinner android:id="@+id/your_spinner_id" <!-- 其余原有属性保持不变 --> />
3. 优化原有监听器逻辑
你原有逻辑基本不需要修改,仅需要补充异常分支、API请求回调中的界面状态恢复逻辑,避免请求出错后界面无法操作:
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { if (isNetworkAvailable()) { progressBar.setVisibility(View.VISIBLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); try { if (position == 0) { progressBar.setVisibility(View.GONE); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); return; } else { changePath(position, arrayitem.get(position)); // 请在changePath方法的API请求回调(成功/失败)中统一添加以下逻辑,恢复界面操作 // progressBar.setVisibility(View.GONE); // getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); } } catch (JSONException e) { e.printStackTrace(); // 异常分支恢复界面状态 progressBar.setVisibility(View.GONE); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); } } } @Override public void onNothingSelected(AdapterView<?> parent) { } });
内容的提问来源于stack exchange,提问作者Malhotra
相关产品推荐
相关产品推荐

