1

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");
        }
    }
});
svstackoverflow
  • 665
  • 6
  • 19
  • 1
    Have you tried using the [InstantAutoComplete class here](https://stackoverflow.com/a/5783983/9473786)? It works for me with your desired behavior - no need for the text and focus listeners either. – Tyler V Jan 07 '22 at 02:09
  • @Tyler V - No, I hadn't come across that post. I was able to get it to work between the use of OnFocusChangeListener and OnKeyListener but this looks to be better. The only flaw was I would need to backspace the twice after the last character before the list would pop. I will try your suggestion and respond back. Thanks for the input!! – svstackoverflow Jan 07 '22 at 11:44
  • @Tyler V - Your suggestion worked. If you can post the answer, I will mark it as the solution so you get credit when it is checked. :) – svstackoverflow Jan 11 '22 at 18:44
  • @Tyler V - At first the InstantAutoCompete class appeared to work, but after switching back between activities it stopped working all together. My use of the listeners were more consistent. At times the user may have to do an extra backspace whereas when I did that with the class it stopped working... it also messed up my alphabetic sequence of the lists. Thanks for the suggestion... it did work at first. So appreciate it. – svstackoverflow Jan 11 '22 at 19:05
  • Weird, maybe related to [this](https://stackoverflow.com/a/11321118/9473786)? – Tyler V Jan 11 '22 at 19:06
  • @Tyler V - Hmm, that is interesting. It could be related because I have multiple AutoCompleteTextViews in one activity. – svstackoverflow Jan 11 '22 at 19:28

1 Answers1

1

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.

Tyler V
  • 9,694
  • 3
  • 26
  • 52
  • Sorry for the late response and thanks for the example... Question, it looks like the `InstantAutoComplete` is embedded within the `TextInputLayout` which I'm unfamiliar (just never used). So would my existing `AutoCompleteTextView` just become the `TextInputLayout` and it's settings remain, and then I add the embedded `InstantAutoComplete`? Am I understanding correctly? – svstackoverflow Jan 13 '22 at 14:22
  • 1
    You could try it without embedding it in the `TextInputLayout` if you wanted - those are decorator containers that are useful for adding [material design features](https://material.io/components/text-fields/android) to text fields. If you did put it in the `TextInputLayout`, some settings (layout) would apply to the container but some would still apply to the AutoComplete (the adapter still gets set on the AutoComplete, not the container). – Tyler V Jan 13 '22 at 14:37
  • That worked! I just replaced my `AutoCompleteTextView` to the `.InstantAutoComplete` and your revisions worked both in keeping them in order and taking care of the extra backspace. Awesome! Again, thanks for your patience and willingness to work through it with me. – svstackoverflow Jan 13 '22 at 18:16