How to avoid getting both called: onItemClicked and onTextChanged on AutoCompleteTextView
Asked Answered
I

2

26

I have this code. When I choose an item from suggestion list, the onTextChanged happens first, then oItemClicked comes after that. Now I want when choosing a word, the "onItemClicked" appears first, then "onTextChanged". I took a look Android doc but it doesn't mention this topic.

package com.autocompletetest;


import java.util.Arrays;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;

public class OnItemClickAndOnTextChangedActivity extends Activity implements TextWatcher, OnItemClickListener {
    private AutoCompleteTextView textView;

    private static final String[] TEMP = new String[] {
        "Beep", "Belgium", "Best", "Bubble", "Bye"
    };
    @Override
    protected void onCreate(final Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        textView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
        textView.setOnItemClickListener(this);
        textView.addTextChangedListener(this);
        textView.setThreshold(1);

        final List<String> list = Arrays.asList(TEMP);

        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                OnItemClickAndOnTextChangedActivity.this,
                android.R.layout.simple_dropdown_item_1line, list);
        textView.setAdapter(adapter);
    }

    @Override
    public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
        System.out.println("OnTextChanged.");
    }

    @Override
    public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
        System.out.println("OnItemClick.");
    }

    @Override
    public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
    }

    @Override
    public void afterTextChanged(final Editable s) {

    }

}

Update: In detail, this is real thing I want to do. Something is not related to question title.

package com.autocompletetest;


import java.util.Arrays;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;

public class OnItemClickAndOnTextChangedActivity extends Activity implements TextWatcher, OnItemClickListener {
    private AutoCompleteTextView textView;
    private boolean itemClicked;

    private static final String[] TEMP = new String[] {
        "Beep", "Belgium", "Best", "Bubble", "Bye"
    };
    @Override
    protected void onCreate(final Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        textView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
        textView.setOnItemClickListener(this);
        textView.addTextChangedListener(this);
        textView.setThreshold(1);

        final List<String> list = Arrays.asList(TEMP);

        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                OnItemClickAndOnTextChangedActivity.this,
                android.R.layout.simple_dropdown_item_1line, list);
        textView.setAdapter(adapter);
    }

    @Override
    public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
        System.out.println("OnTextChanged.");

        // The below code block does:
        // When type a word, make a new ArrayAdapter and set it for textView
        // If any of word in suggestion list is clicked, nothing changes, dropdown list not shown.
        if(itemClicked) {
            itemClicked = false;
        } else {
            // Create new ArrayAdapter.
            // textView is set to new ArrayAdapter.
            // textView.showDropDown()
        }
    }

    @Override
    public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
        System.out.println("OnItemClick.");
        itemClicked = true;
    }

    @Override
    public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
    }

    @Override
    public void afterTextChanged(final Editable s) {

    }
}
Irreparable answered 14/8, 2011 at 7:9 Comment(5)
did u check when beforeTextChanged() called.?Tiddly
Why cant u do all the stuff in OnclickListener()?Tiddly
Yes, I did. ALL functions of TextWatcher occurs before onItemClick.Irreparable
Note to readers: Don't stop with accepted answer below, read down to the real solution in the answer lower down: https://mcmap.net/q/512633/-how-to-avoid-getting-both-called-onitemclicked-and-ontextchanged-on-autocompletetextviewEllipsis
You may also want to try overriding the replaceText methodEndanger
W
102

isPerformingCompletion() was added in API Level 3. It returns true after an item has been selected from the drop-down list and TextWatcher listeners are about to be triggered. In short, to avoid the behaviour described:

public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (autoCompleteView.isPerformingCompletion()) {
        // An item has been selected from the list. Ignore.
        return;
    }

    // Your code for a general case
}
Wakefield answered 19/7, 2012 at 14:54 Comment(0)
D
0

There is no particular solution for this problem.I will suggest that you should put code on which is in inside onclicklistener() in the begining of textchangedlistener() so that the code that u want to get execute first will execute first then the code that you want to get execute last will execute last.Hope this will help you.

Detonation answered 14/8, 2011 at 7:46 Comment(2)
Actually I have a boolean var "itemClicked", it will be true when click an item in suggestion list. I want to check "itemClicked" every time text changes. The problem is.. after a word is clicked, onTextChanged occurs before onItemClicked.Irreparable
You can do one thing.As i said there is o particular solution as textchange will be called first.So you put your code that is inside textChangedListener() inside a function and call that function in the end of onItemClicked().This will work i think.Detonation

© 2022 - 2024 — McMap. All rights reserved.