Search code examples
androidlistviewspinnerandroid-arrayadapterandroid-spinner

getView called repetitively with setOnItemSelectedListener even when Visibility.GONE


I am working on a listView that will contain items that contain a custom spinner. The goal of what I am trying to do is to have an entry in each spinner, where when selected, the spinner itself will disappear and an edit text will appear.

In this sample I have provided, I am creating an entry in the spinner called "Create New" and when selected, an edit text should appear allowing you to type in a new name.

The issue I am seeing is when "Create New" is selected, the spinner will change to visibility.GONE and the edit text is shown. however you can never select the edit text. I believe getView is constantly being called and is possibly messing up what I am trying to accomplish.

Any tips would be great!


Activity.java

public class Activity extends ListActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);

        List<String> categories = new ArrayList<>();
        categories.add("Groceries");
        categories.add("Gas");
        categories.add("Travel");

        List<String> entries = new ArrayList<>();
        entries.add("first");
        entries.add("second");
        entries.add("third");

        ListView listView = (ListView) findViewById(android.R.id.list);
        listView.setAdapter(new ListAdapter(entries, categories));
    }

    private class ListAdapter extends ArrayAdapter<String> {
        SpinnerAdapter spinnerAdapter;
        public ListAdapter(List<String> entries, List<String> categories) {
            super(Activity.this, 0, entries);
            spinnerAdapter = new SpinnerAdapter(categories);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = getLayoutInflater().inflate(R.layout.list_item, parent, false);
            }

            final Spinner spinner = (Spinner) convertView.findViewById(R.id.spinner);
            final EditText categoryEditText = (EditText) convertView.findViewById(R.id.edit_text);

            spinner.setAdapter(spinnerAdapter);
            spinner.setSelection(spinnerAdapter.getCount());
            spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    // if the create item was selected, hide the spinner and show the edit text
                    if (position == spinnerAdapter.getCount()-1) {
                        spinner.setVisibility(View.GONE);
                        categoryEditText.setVisibility(View.VISIBLE);
                    }
                }

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

                }
            });

            return convertView;
        }

        private class SpinnerAdapter extends ArrayAdapter<String> {
            public SpinnerAdapter(List<String> categories) {
                super(Activity.this, android.R.layout.simple_spinner_dropdown_item, categories);
                categories.add("Create New");
                categories.add("Choose a Category");
                this.notifyDataSetChanged();
            }

            @Override
            public int getCount() {
                return super.getCount() - 1; // last item is a place holder
            }


        }
    }
}

activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

        <ListView
                android:id="@android:id/list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/white">
        </ListView>

</LinearLayout>

list_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="horizontal"
              android:layout_width="match_parent"
              android:layout_height="wrap_content">

    <EditText
            android:id="@+id/edit_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone"/>

    <Spinner
            android:id="@+id/spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

</LinearLayout>

On Launch launch

Drop Down Open drop down open

Select Create New and EditText appears, however it wont hold focus making it not editable edit text that is not selectable


Solution

  • I found a solution to my problem. It turns out the real issue is having an Edit Text inside a ListView. I had to set this flag on my Activity definition in my Manifest and everything just worked!

    <activity android:name= ".Activity" android:windowSoftInputMode="adjustPan"/>
    

    Maybe someone would like to give more clarification? If so I will mark your answer as the correct one.