Catching an event when spinner drop down is dismis

2019-04-04 04:19发布

问题:

I want to catch an event when spinner drop down is dismissed. We can catch it when the user clicks on any item in the onItemSelected(). But I want to catch even when user touches outside of the drop down area or back button as these too make it disappear. In these two causes when I observed log, it says "Attempted to finish an input event, but the input event receiver has already been disposed"

I observed the source code, this is printed from the InputEventReceiver.java in the finishInputEvent(InputEvent event, boolean handled) method. But it's a final method, so there is no point of overriding it. Can some one please suggest the way to handle when the drop down is dismissed in those cases?

回答1:

I have used Popup Menu instead of Spinner. Because as far as my knowledge, dismiss event couldn't be caught with spinner, but with Popup menu I did it by setting onDismissListerner() to the popup menu

popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {  
             public boolean onMenuItemClick(MenuItem item) {  
              Toast.makeText(MyActivity.this,"Clicked on: " + item.getTitle(),Toast.LENGTH_LONG).show();  
              return true;  
             }  
            });  
popup.setOnDismissListener (new PopupMenu.OnDismissListener(){

public void onDismiss()
{
   //catch dismiss event here.
}
});


回答2:

If you really don't need to use the spinner try using this code.
ListView inside Dialog. You can listen for the Cancel/dismiss event of the dialog(Same thing). You can use this in API 11.

final Dialog dialog = new Dialog(context);
            dialog.setContentView(R.layout.custom_list_popup);
            //dialog.setCancelable(false);
            dialog.setTitle("Title");

            dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    //
                    //Do your onCancel things here
                    //
                }
            });


            final ListView listView = (ListView) dialog.findViewById(R.id.lv_sales_tax);
            listView.setAdapter(adapter);

            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                    //
                    //Do your stuff here
                    //

                    dialog.dismiss();
                }
            });

            dialogButton.setVisibility(View.GONE);
            dialog.show();

        }
    });

contents of custom_list_popup.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="20dp"
android:orientation="vertical">

<ListView
    android:id="@+id/lv_sales_tax"
    android:divider="@drawable/list_divider"
    android:dividerHeight="20dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

</LinearLayout>


回答3:

What about looking for another event like onDetachFromWindow? A spinner doesn't have any of the regular lifecycle events that we work with a lot -- it would be nice to have an onStop or onDestroy to work with. Of course, you would have to extend the spinner class and create an interface to define your own listener:

public class ChattySpinner extends Spinner {
    private ChattySpinnerListener chattyListener;

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

    public ChattySpinner(Context context, int mode) {
        super(context, mode);
    }

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

    public ChattySpinner(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public ChattySpinner(Context context, AttributeSet attrs, int defStyle, int mode) {
        super(context, attrs, defStyle, mode);
    }

    public void setChattyListener(ChattySpinnerListener listener) {
        this.chattyListener = listener;
    }

    @Override
    protected void onDetachedFromWindow() {
        if(chattyListener != null) {
            chattyListener.onDetach();
        }

        super.onDetachedFromWindow();
    }

    public interface ChattySpinnerListener {
        public void onDetach();
    }
}

And in your layout XML you want to make sure you specify this control instead of your normal spinner, and in your code set the listener with the implementation of whatever you want to have done when the spinner detaches. It will be up to you to figure out on the client side how to track whether something has been selected or not, maybe by setting a variable in the onItemSelected method that you give the selection listener.