AppCompatSpinner's entries not opening TimePickerDialog on selecting it second time. Please see details
Asked Answered
V

2

8

I have the following as AppCompatSpinner's entries:

<string-array name="startTimeList">
    <item>Now</item>
    <item>Pick a time..</item>
</string-array>

Upon selecting Pick a time.., a TimePickerDialog is opened and the user is allowed to choose a time. Here's how:

startTimeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
//                startTimeString = adapterView.getItemAtPosition(i).toString();
                DateFormat currentDateFormat = new SimpleDateFormat("HH:mm:ss");
                userAvailableTimeInSF = currentDateFormat.format(new Date());

                final TextView startTimeSpinnerTV = (TextView) adapterView.getSelectedView();
                startTimeSpinnerTV.setText(userAvailableTimeInSF);

                switch (i) {
                    case 0:

                        userAvailableTimeInSF = currentDateFormat.format(new Date());
                        startTimeSpinnerTV.setText("Now");
                        break;

                    default:

                        final Calendar c = Calendar.getInstance();
                        mHour = c.get(Calendar.HOUR_OF_DAY);
                        mMinute = c.get(Calendar.MINUTE);

                        TimePickerDialog timePickerDialog = new TimePickerDialog(PostSportRequest.this,
                                new TimePickerDialog.OnTimeSetListener() {

                                    @Override
                                    public void onTimeSet(TimePicker view, int hourOfDay,
                                                          int minute) {

                                        Calendar date = Calendar.getInstance();
                                        date.set(Calendar.HOUR_OF_DAY, hourOfDay);
                                        date.set(Calendar.MINUTE, minute);
                                        date.set(Calendar.AM_PM, date.get(Calendar.AM_PM));

                                        showTime(hourOfDay, minute);

                                        userAvailableTimeInSF = new SimpleDateFormat("HH:mm:ss").format(date.getTime());
                                        startTimeSpinnerTV.setText(userAvailableTimeAMPM);

                                        Toast.makeText(getBaseContext(), "userAvailableTimeInSF: " + userAvailableTimeInSF, Toast.LENGTH_SHORT).show();

                                    }
                                }, mHour, mMinute, false);
                        timePickerDialog.show();
                        break;
                }

            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {

            }
        });

Upon selecting Pick a time.. the first time, TimePickerDialog is successfully opened and the chosen time is shown but when I choose it again or click on it again, nothing happens!

I don't know why!

Please let me know how can I get the TimePickerDialog opened and chose the time no matter how many times I select/click it.

Vin answered 22/11, 2016 at 17:45 Comment(7)
@SuryaPrakashKushawah bro, I have explained as clearly as I can in the question. See this line: "Upon selecting Pick a time.. the first time, TimePickerDialog is successfully opened and the chosen time is shown but when I choose it again or click on it again, nothing happens!"Vin
What is i ? and are you getting Toast message on second selection ?Choral
@ρяσѕρєяK int i is a parameter in onItemSelected() and yes, I get the Toast message first time but then if without selecting case 0 first I select case 1 again, nothing happens! As described in the answer below by @MarcinJedynak His approach didn't worked for me!Vin
@HammadNasir: Ok then change case 1: to default: and check getting Dialog every time excluding 0Choral
@ρяσѕρєяK it didn't helped! Please see the edited question and also have a look at Marcin's answer below. He has a good reason about why is this happening.Vin
@HammadNasir: Then add "Select time..." as first default item and hide it on opening of SpinnerChoral
I know its late, but you can check this answer: https://mcmap.net/q/272016/-how-can-i-get-an-event-in-android-spinner-when-the-current-selected-item-is-selected-againLeacock
T
6

Follow these steps:

Create a custom spinner class

    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.Spinner;

    public class SpinnerOnSameSelection extends Spinner {
        OnItemSelectedListener listener;
        private AdapterView<?> lastParent;
        private View lastView;
        private long lastId;

        public SpinnerOnSameSelection(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
            initlistner();
        }

        @Override
        public void setSelection(int position) {
            if (position == getSelectedItemPosition() && listener != null) {
                listener.onItemSelected(lastParent, lastView, position, lastId);
            } else {
                super.setSelection(position);
            }

        }

        private void initlistner() {
            // TODO Auto-generated method stub
            super.setOnItemSelectedListener(new OnItemSelectedListener() {

                @Override
                public void onItemSelected(AdapterView<?> parent, View view,
                                           int position, long id) {
                    // TODO Auto-generated method stub
                    lastParent = parent;
                    lastView = view;
                    lastId = id;
                    if (listener != null) {
                        listener.onItemSelected(parent, view, position, id);
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    // TODO Auto-generated method stub
                    if (listener != null) {
                        listener.onNothingSelected(parent);
                    }
                }
            });

        }

        public void setOnItemSelectedEvenIfUnchangedListener(
                OnItemSelectedListener listener) {
            this.listener = listener;
        }

}

Create onItemSelectedListener in your activity

private AdapterView.OnItemSelectedListener listener;

 listener = new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> adapterView, View arg1,
                                       int i, long arg3) {

                //startTimeString = adapterView.getItemAtPosition(i).toString();
                DateFormat currentDateFormat = new SimpleDateFormat("HH:mm:ss");
                userAvailableTimeInSF = currentDateFormat.format(new Date());

                final TextView startTimeSpinnerTV = (TextView) adapterView.getSelectedView();
                startTimeSpinnerTV.setText(userAvailableTimeInSF);

                switch (i) {
                    case 0:

                        // userAvailableTimeInSF = currentDateFormat.format(new Date());
                        startTimeSpinnerTV.setText("Now");
                        break;

                    case 1:

                        final Calendar c = Calendar.getInstance();
                        mHour = c.get(Calendar.HOUR_OF_DAY);
                        mMinute = c.get(Calendar.MINUTE);

                        TimePickerDialog timePickerDialog = new TimePickerDialog(MainActivity.this,
                                new TimePickerDialog.OnTimeSetListener() {

                                    @Override
                                    public void onTimeSet(TimePicker view, int hourOfDay,
                                                          int minute) {

                                        Calendar date = Calendar.getInstance();
                                        date.set(Calendar.HOUR_OF_DAY, hourOfDay);
                                        date.set(Calendar.MINUTE, minute);
                                        date.set(Calendar.AM_PM, date.get(Calendar.AM_PM));

                                        //showTime(hourOfDay, minute);

                                       /* userAvailableTimeInSF = new SimpleDateFormat("HH:mm:ss").format(date.getTime());
                                        startTimeSpinnerTV.setText(userAvailableTimeAMPM);*/

                                        Toast.makeText(getBaseContext(), "userAvailableTimeInSF: " + userAvailableTimeInSF, Toast.LENGTH_SHORT).show();

                                    }
                                }, mHour, mMinute, false);
                        timePickerDialog.show();
                        break;
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub

            }
        };
}

Add the listener object to custom spinner method

SpinnerOnSameSelection startTimeSpinner;

in onCreate(): startTimeSpinner = (SpinnerOnSameSelection) findViewById(R.id.idOfItemInXml);

startTimeSpinner.setOnItemSelectedEvenIfUnchangedListener(listener);

In Your xml File

<your_package_name.SpinnerOnSameSelection
    android:id="@+id/startTimeSpinner"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:layout_alignParentBottom="true"
    android:entries="@array/mList">
</your_package_name.SpinnerOnSameSelection>
Tuttifrutti answered 21/12, 2016 at 8:48 Comment(6)
No...pl try this..This meets to your requirement.Tuttifrutti
is SpinnerOnSameSelection an inner class or a separate file?Vin
Its Separate Class.Tuttifrutti
then how am I supposed to have it's access here: startTimeSpinner.setOnItemSelectedEvenIfUnchangedListener(listener); which is in another class? I'm getting Cannot resolve method error on this line.Vin
Let us continue this discussion in chat.Tuttifrutti
please respond, buddy.Vin
I
3

Spinner (or actually AdapterView, its superclass), fires OnItemSelectedListener only when the selection changes.

When your user selects "Pick a time..." Spinner assumes it is a selected option, and won't call the listener anymore if it is selected again. You can however notice, that if "Pick a time..." is selected, then "Now" and then "Pick a time...", the dialog appears.

I would recommend against using Spinner in your case (and doing some weird shit with the selected view). You can simply accomplish the same with TextView that displays the selected time and two buttons - one to show the dialog and one to reset the time to now.

Infuscate answered 22/11, 2016 at 18:9 Comment(3)
I need to use the Spinner. Please let me know how to achieve it using it only.Vin
Maybe add an additional option with your selected time. When the user picks the time, just change the text of your additional option and programmatically select it (setSelection(int)). That way "Pick a time..." will be always treated as newly selected.Infuscate
User can select any time he wants, how many other options can I add? There can be a lot of possibilities!Vin

© 2022 - 2024 — McMap. All rights reserved.