Android spinner close

2019-01-14 18:05发布

I have an activity with a spinner, and I was wondering if it is possible to close the spinner programmatically, if the user has opened it.

The whole story is that in the background I am running a process on a separate thread. When the process has finished, I invoke a Handler on the main activity and, depending on the outcome, I perform some tasks. It is then that I want to close the spinner, it the user has opened it.

The spinner is in the main.xml layout:

<Spinner android:id="@+id/birthPlaceSpinner" android:layout_weight="1" 
android:layout_height="wrap_content" android:prompt="@string/select"
android:layout_width="fill_parent" />

and this is the Handler:

private class BirthplaceChangedHandler extends Handler {

    @Override
    public void handleMessage(Message msg) {
        String placeFilterStr = birthPlaceFilterText.getText().toString();
        if ("".equals(placeFilterStr) || placeFilterStr == null || validNewAddresses.isEmpty()) {
            birthPlaceSpinner.setEnabled(false);
            hideGeoLocationInformation();
        } else {
            birthPlaceSpinner.setEnabled(true);
        }
        adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.multiline_spinner_dropdown_item, validNewAddressesStr)
        birthPlaceSpinner.setAdapter(adapter);
    }
}

Cheers!

8条回答
倾城 Initia
2楼-- · 2019-01-14 18:42
  public static void hideSpinnerDropDown(Spinner spinner) {
    try {
        Method method = Spinner.class.getDeclaredMethod("onDetachedFromWindow");
        method.setAccessible(true);
        method.invoke(spinner);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
查看更多
够拽才男人
3楼-- · 2019-01-14 18:43

Well its a little complicated than I thought.

I am adding the step by step details here. Try to follow it. I was able to achieve this in api level 10.

And this solution assumes that you are supposed to close the prompt dialog programatically when the user clicks on Home Button or If you had to move to next activity without user interaction

The first step is to create a Custom Spinner by extending Spinner Class. Let's say, I have created a class called CustomSpinner in the package com.bts.sampleapp

My CustomSpinner class looks like this,

package com.bts.sampleapp;

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

    public class CustomSpinner extends Spinner{
        Context context=null;

        public CustomSpinner(Context context) {
            super(context);
            this.context=context;
        }

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

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

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

Now in your Xml file, replace Spinner element by this custom spinner,

        <com.bts.sampleapp.CustomSpinner
        android:id="@+id/spin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

The next step is to initialize and set adapter to this spinner in your Activity class,

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    CustomSpinner spin=null;
    spin=(CustomSpinner)findViewById(R.id.spin);
    spin.setAdapter(spinnerAdapter); //you can set your adapter here.
}

The final step is to close the dialog when the user clicks on HomeButton or When the Activity moves to background. To do this, we override the onPause() like this,

@Override
    protected void onPause() {
        Log.i("Life Cycle", "onPause");
        spin.onDetachedFromWindow();
        super.onPause();
    }

Now within the onPause() call the method spin.onDetachedFromWindow(); which does the job of closing the prompt dialog for you.

Now that being said, calling spin.onDetachedFromWindow(); from anywhere in your Activity should help you to close the spinner programatically. So if this is what you want, then remove the onpause().

查看更多
三岁会撩人
4楼-- · 2019-01-14 18:44

I don't see a way to accomplish that -- there is no method on Spinner to close it. The "open" part of a Spinner is an AlertDialog on Android 1.x and 2.x, and I'm not completely sure how it is implemented on Honeycomb when using the holographic theme.

The only workaround would be to clone the source for Spinner and add in some code yourself to dismiss the dialog. But, again, it would not work on Honeycomb or higher until you can see and clone that code as well.

Beyond that, I would think that what you want is poor UX. If the user opened the Spinner, they are most likely actively examining the Spinner's contents and making a selection. Yanking that out from under their finger will confuse them, at best. Please consider an alternative approach.

Also, don't use getApplicationContext() unless you know why you are using getApplicationContext(). You do not need or even want getApplicationContext() when creating an ArrayAdapter.

查看更多
\"骚年 ilove
5楼-- · 2019-01-14 18:49

Use the clearFocus() to close the spinner programitically

spinner.clearFocus();
查看更多
孤傲高冷的网名
6楼-- · 2019-01-14 18:50

I think you should scrap your use of Spinner and instead use an ImageView with a Frame Animation (i.e. <animation-list>) to create your own spinner. You just set the ImageView's background to be your Frame Animation drawable.

Then you can easily do something like this to start and stop it.

查看更多
虎瘦雄心在
7楼-- · 2019-01-14 18:50

What about cloning a 'back' keystroke?

Ok I just tried

[current activity].dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_BACK));

and it didn't do anything that I could see--then pressed physical back key and the drop down went away. Also tried doing a ACTION_UP right after the down--no effect either.

查看更多
登录 后发表回答