首页 > 解决方案 > 如何将 Spinner 用作 ACTION 而不是 SELECTION?

问题描述

是否有可能将微调器用作动作功能而不是选择?当用户单击微调器视图时,会弹出一些项目,当前微调器允许我们选择项目,这意味着当用户单击第一个项目时,将启动 onItemSelected 回调,并且下次单击同一项目时不会发生任何事情( ) 甚至 OnNothingSelected 也没有被调用。即使用户连续多次单击同一项目,如何修改它以使其成为操作(例如打印你好世界)。在没有用户交互的情况下调用 onItemSelected 时还有另一个问题。我尝试添加一些布尔值来控制用户是否单击或在启动时调用它,但由于选择相同项目时未选择项目而无法正常工作。换句话说,我想添加在添加时崩溃的 onItemClick listetner。

标签: javaandroidviewspinnerandroid-adapter

解决方案


正如官方文档中所说:

微调器不支持项目单击事件。调用此方法将引发异常。

但我找到了这个解决方案,可以在下面的链接中知道 Spinner 是打开还是关闭。我修改它以在 Spinner 关闭时获取 ItemSelected https://stackoverflow.com/a/18636385/7085389

您需要像下面的代码一样创建自定义 Spinner

import android.content.Context;
import android.util.AttributeSet;

    public class CustomSpinner extends androidx.appcompat.widget.AppCompatSpinner {
        // implement the Spinner constructors that you need
    
        public CustomSpinner(Context context) {
            super(context);
        }
    
    
        public CustomSpinner(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
    
        private OnSpinnerItemSelected mListener;
        private boolean mOpenInitiated = false;
    
    
        @Override
        public boolean performClick() {
            // register that the Spinner was opened so we have a status
            // indicator for when the container holding this Spinner may lose focus
            mOpenInitiated = true;
            return super.performClick();
        }
    
        @Override
        public void onWindowFocusChanged(boolean hasFocus) {
            if (hasBeenOpened() && hasFocus) {
                performClosedEvent();
            }
        }
    
        /**
         * Register the listener which will listen for events.
         */
        public void setOnSpinnerItemSelected(
                OnSpinnerItemSelected onSpinnerItemSelected) {
            mListener = onSpinnerItemSelected;
        }
    
        /**
         * Propagate the closed Spinner event to the listener from outside if needed.
         */
        public void performClosedEvent() {
            mOpenInitiated = false;
            if (mListener != null) {
                mListener.onSelect(this.getSelectedItem());
            }
        }
    
        /**
         * A boolean flag indicating that the Spinner triggered an open event.
         *
         * @return true for opened Spinner
         */
        public boolean hasBeenOpened() {
            return mOpenInitiated;
        }
    
        /**
         * An interface which a client of this Spinner could use to receive
         * open/closed events for this Spinner.
         */
        public interface OnSpinnerItemSelected {
            /**
             * Callback triggered when the spinner was closed.
             */
            void onSelect(Object item);
        }
    }

你可以像下面的代码一样使用它:

 spinner.setOnSpinnerItemSelected(new CustomSpinner.OnSpinnerItemSelected() {
            @Override
            public void onSelect(Object item) {
                Log.d(TAG, "onSelect: "+item);
            }
        });

推荐阅读