svstackoverflow
svstackoverflow

Reputation: 723

Why won't the AutoCompleteTextView.showDropDown() not trigger on call?

Problem: MyAutoCompleteTextView.**showDropDown()** will work when called by the onFocusChange but won't work when called by the onTextChanged. During my debug, the onTextChanged method gets called correctly when I want it to execute the showDropDown() according to the logging message I created, just nothing happens. I noticed there is a SpannableStringBuilder error that occurs prior, but as I recall (could be wrong) when I checked on this error in the past, this is a common error with an open ticket. I wasn't really sure it is the cause.

What I'm trying to do: ... is what everyone that asks this type of question wants to do, get the AutoCompleteTextView to show the full list anytime the AutoCompleteTextView is focused and empty (my first item is: "")

What I have tried: I've tried many "green checked" solutions on this forum, but none of them have worked at present EXCEPT when first focused. They will cause the full items list to present, but it is on the backspacing back to zero that it will not. I'm using a combination of change listeners as most suggestions have. I just really thought this would work based on the logging values and it being called at the proper time?

My logging statement: which writes when I want it to showing the method gets called when I like.

E/SpannableStringBuilder: SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
    SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
E/OnTextChanged: showDropDown() 
    start: 0
    before: 1
    count: 0
    length: 0

My current version and effort:

 ArrayAdapter<String> topicsAdapter = DBQueryTools.captureDBTopics(this);
topic.setAdapter(topicsAdapter);
topic.setOnItemClickListener((parent, view, position, id) -> {
    if(!topic.getText().toString().equals("")) {
        question.setText("");
        rListNotes.setAdapter(null);
        customSearch.setText(null);
        loadNotes(captureNotes(researchDatabase.getNotesDao().getNotesOnTopic(topic.getText().toString())));
    }
});

topic.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(before == 1 && count == 0 && s.length()==0) {
            topic.showDropDown();
            Log.e("OnTextChanged", "showDropDown() " + s + "\n" + "start: " + start + "\nbefore: " + before + "\ncount: " + count + "\nlength: " + s.length());
        }
    }

    @Override
    public void afterTextChanged(Editable s) {

    }
});
topic.setOnFocusChangeListener(new View.OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            topic.showDropDown();
            Log.e("HasFocus", "showDropDown");
        }
    }
});

Upvotes: 1

Views: 498

Answers (1)

Tyler V
Tyler V

Reputation: 10910

I was able to get a modified version of the InstantAutoComplete view working (combining from here and here)

public class InstantAutoComplete extends AppCompatAutoCompleteTextView {

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

    public InstantAutoComplete(Context arg0, AttributeSet arg1) {
        super(arg0, arg1);
    }

    public InstantAutoComplete(Context arg0, AttributeSet arg1, int arg2) {
        super(arg0, arg1, arg2);
    }

    @Override
    public boolean enoughToFilter() {
        return true;
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction,
                                  Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        if (focused && getAdapter() != null) {
            // This part was necessary to get it working when not
            // inside a TextInputLayout and multiple per activity
            if( !maybeShowSuggestions() ) {
                post(this::maybeShowSuggestions);
            }
        }
    }

    private boolean maybeShowSuggestions() {
        if( getWindowVisibility() == View.VISIBLE ) {
            performFiltering(getText(), 0);
            showDropDown();
            return true;
        }
        else {
            return false;
        }
    }
}

The XML for inserting it looks like (also worked without the TextInputLayout)

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/text_layout"
    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Type words here"
    android:layout_margin="16dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@id/focus_stealer" >

    <com.example.autocompletetextviewdemo.InstantAutoComplete
        android:id="@+id/autocomplete_text_view"
        android:layout_width="match_parent"
        android:completionThreshold="0"
        android:layout_height="wrap_content"/>

</com.google.android.material.textfield.TextInputLayout>

and for setting it up with an adapter

    private static final String[] WORDS = new String[] {
        "Aardvark", "Apple", "Baby", "Boron", "Carbon"
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_dropdown_item_1line, WORDS);
        AutoCompleteTextView textView = findViewById(R.id.autocomplete_text_view);
        textView.setAdapter(adapter);   
    }

This works with multiple InstantAutoComplete dropdowns per activity, and after navigating back and forth between activities. Without the extra changes to the custom class it didn't work with multiple instances in an activity that weren't in a TextInputLayout.

Upvotes: 1

Related Questions