如何避免在AutoCompleteTextView上同时触发onItemClicked和onTextChanged?

26

我有以下代码。当我从建议列表中选择一个项时,onTextChanged先触发,然后oItemClicked在其后触发。现在我想让选择一个单词时,“onItemClicked”先出现,然后是“onTextChanged”。我查看了Android文档,但它没有提到这个主题。

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) {

    }

}

更新: 详细来说,这是我想要做的真正的事情。它与问题标题无关。

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) {

    }
}

你有检查 beforeTextChanged() 什么时候被调用吗? - Ron
为什么不能在OnClickListener()中完成所有的事情? - Ron
1
是的,我做到了。TextWatcher的所有函数在onItemClick之前发生。 - emeraldhieu
读者注意:不要仅停留在下面被接受的答案,继续往下阅读真正的解决方案:https://dev59.com/U2w05IYBdhLWcg3wv0V6#11563527 - Anne Gunn
您可能还想尝试覆盖replaceText方法 - Chepech
2个回答

103

isPerformingCompletion()在API Level 3中添加。在从下拉列表中选择一个项目且准备触发监听器之后,它将返回true。简而言之,要避免所描述的行为:

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
}

0

对于这个问题,没有特定的解决方案。我建议您应该将onclicklistener()中的代码放在textchangedlistener()的开头,这样您想要先执行的代码就会首先得到执行,然后您想要最后执行的代码就会最后得到执行。希望这可以帮助到你。


实际上,我有一个布尔变量“itemClicked”,当在建议列表中点击项目时,它将为true。我想每次文本更改时都检查“itemClicked”。问题是...在单击单词后,在onItemClicked之前会发生onTextChanged。 - emeraldhieu
你可以这样做。就像我说的,没有特定的解决方案,因为textchange将首先被调用。所以你可以把在textChangedListener()中的代码放到一个函数里,在onItemClicked()的结尾处调用该函数。我认为这会起作用。 - Android Killer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接