AutoCompleteTextView在Android 2.3.5中没有显示建议。

4
我正在使用特殊的自动完成文本视图来提供成千上万条街道的建议。由于这个巨大的元素列表,我必须根据第一个输入字母实时清除和填充适配器。例如,当用户输入“b”时,适配器将被填充以所有以“b”开头的街道。这在所有Android版本中都有效。今天有一个用户告诉我,在Android 2.3.5,三星Galaxy Ace上存在问题。
当他开始输入字母时,没有下拉菜单提供建议。当他输入“b”时,它仅建议由两个名称组成且第二个名称以“b”开头的街道。例如:他对“b”的建议是“Am Bahnhof”或“Alte Bahnstraße”。似乎有一种模式,但我无法解释发生了什么,并且我无法在任何模拟器或实际设备上重现此模式(而且没有2.3.5模拟器)。
以下是代码。只是为了信息:我必须在beforeTextChange中清除它,否则当我非常快地删除字段中的输入时,应用程序会崩溃。显然,它无法快速交换列表。我需要变量alreadyAdded,否则当我将输入删除到第一个字母时,它会将列表添加两次。
真正奇怪的是:自从第一次实现以来,我从未更改过这部分,而用户告诉我它在第一个版本中起作用。但突然间它不再起作用了。编译后的代码是否可能被损坏?有什么想法吗?
如果有人能告诉我如何重现这个问题,我也可以接受解决方案。
调用:
autoCompleteTextView.addTextChangedListener(new StreetTextWatcher(adapter));

StreetArrayAdapter:

public class StreetArrayAdapter extends ArrayAdapter<String> {

    public StreetArrayAdapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);
    }

    public void addAll(String[] streets) {
        for (String street : streets) {
            add(street);
        }
    }
}

StreetTextWatcher:

public class StreetTextWatcher implements TextWatcher {

    private final StreetArrayAdapter adapter;
    private boolean alreadyAdded = false;

    public StreetTextWatcher(StreetArrayAdapter adapter) {
        this.adapter = adapter;
    }

    @Override
    public void afterTextChanged(Editable s) {
        //not used
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        if (s.length() < 1)  {
            adapter.clear();

            alreadyAdded = false;
        }
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {           
        if (s.length() == 1) {
            populateAdapter(s);

            alreadyAdded = true;
        }
    }

    private void populateAdapter(CharSequence s) {  
        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("a") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_A);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("ä") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_A);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("b") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_B);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("c") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_C);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("d") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_D);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("e") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_E);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("f") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_F);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("g") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_G);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("h") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_H);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("i") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_I);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("j") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_J);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("k") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_K);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("l") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_L);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("m") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_M);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("n") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_N);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("o") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_O);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("ö") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_O);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("p") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_P);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("q") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_Q);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("r") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_R);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("s") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_S);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("t") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_T);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("u") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_U);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("ü") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_U);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("v") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_V);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("w") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_W);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("y") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_Y);
        }

        if (s.toString().toLowerCase(Locale.GERMAN).startsWith("z") && !alreadyAdded)  {
            adapter.addAll(StreetNames.STREETS_Z);
        }
    }
}

显然有些不同,因为我无法在2.3.3中复现它。 - Bevor
用户是否使用自定义键盘? - StarsSky
@StarsSky 怎么设置自定义键盘?也许我可以在模拟器中检查一下。 - Bevor
1
也许是我的知识不足,但是为什么你要使用Locale.GERMAN?我认为它是用于日期/货币等方面的...在你的情况下,我不明白使用Locale有什么意义,因为用户输入街道名称进行搜索...也许用户缺少Locale.GERMAN?另外请注意还有Locale.GERMANY...而且你应该阅读“小心默认语言环境”..特别是这一行“最好的选择通常是Locale.US——这种语言环境保证在所有设备上都可用..."<-可能缺少德语语言环境。 - chuthan20
据我所知,Locale 用于将 $20.00 转换为欧元。星期四在德语中的等效词是 w/e...或者您有要提供的翻译...例如,默认的“APP_NAME”=“通讯录”,而“APP_NAME”=“某些德语单词”...当一切都设置好并且他们的 Locale 是德语时,他们将看到应用程序名称的德语版本而不是英语版本...所以让我们看看用户对修复的意见。 - chuthan20
显示剩余6条评论
2个回答

2
我提到了优化的问题......但由于我在粘贴代码,所以我想保留格式,因此我将其作为答案粘贴,尽管这并没有回答你的问题。
以下是我编写代码的方式,使其更容易更改/添加/维护...
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) 
{           
    if (s.length() == 1) 
    {
        if (!alreadyAdded)
        {
            alreadyAdded = true;
            populateAdapter(s);
        }
    }
}

private void populateAdapter(CharSequence s) {  
    Object arr[][] = 
    {{"a", StreetNames.STREETS_A },
     {"ä", StreetNames.STREETS_A },
     {"b", StreetNames.STREETS_B },
     {"c", StreetNames.STREETS_C },
     {"d", StreetNames.STREETS_D },
     {"e", StreetNames.STREETS_E },
     {"f", StreetNames.STREETS_F },
     {"g", StreetNames.STREETS_G },
     {"h", StreetNames.STREETS_H },
     {"i", StreetNames.STREETS_I },
     {"j", StreetNames.STREETS_J },
     {"k", StreetNames.STREETS_K },
     {"l", StreetNames.STREETS_L },
     {"m", StreetNames.STREETS_M },
     {"n", StreetNames.STREETS_N },
     {"o", StreetNames.STREETS_O },
     {"ö", StreetNames.STREETS_O },
     {"p", StreetNames.STREETS_P },
     {"q", StreetNames.STREETS_Q },
     {"r", StreetNames.STREETS_R },
     {"s", StreetNames.STREETS_S },
     {"t", StreetNames.STREETS_T },
     {"u", StreetNames.STREETS_U },
     {"ü", StreetNames.STREETS_U },
     {"v", StreetNames.STREETS_V },
     {"w", StreetNames.STREETS_W },
     {"y", StreetNames.STREETS_Y },
     {"z", StreetNames.STREETS_Z }};

    for (int i=0; i<arr.length; i++)
    {
        if (s.toString().toLowerCase(Locale.GERMAN).startsWith(arr[i][0]))  {
            adapter.addAll(arr[i][1]);
            break;
        }
    }
}

这可能不起作用,因为它可能会导致NullPointerExceptions。我不知道为什么会发生这种情况,但当您非常快地删除输入时,它是可重现的。请参见此帖子和我的答案:https://dev59.com/GGnWa4cB1Zd3GeqPzE0d - Bevor
顺便说一下,您从未调用clear。每次用户通过搜索以'a'开头的街道来加载列表以添加更多列表时,他会在字段中删除它以搜索以'b'开头的其他街道,列表会越来越大并变得越来越慢。如果他这样做了3或4次,列表加载需要几秒钟。 - Bevor
我发布这段代码的意思是...只需在您的代码中替换这些方法..这样您就可以拥有所有其他方法,例如beforeTextChanged,它将清除列表..另一种方法是..当用户键入'A'时,获取所有以'A'开头的名称并将其放入tempList中..然后当用户键入下一个字母'Ab'时,则搜索tempList而不是再次搜索所有内容...这样..tempList将继续变短,并使搜索更快。但是当用户按退格键时,您必须从头开始搜索。 - chuthan20

-4

使用以下代码实现自动完成文本框

MainActivity.java

public class MainActivity extends Activity {

AutoCompleteTextView autoCompleteTextView;

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

    autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.AndroidBooks);

    StreetArrayAdapter adapter = new StreetArrayAdapter(MainActivity.this,
            android.R.layout.simple_gallery_item);
    autoCompleteTextView.setThreshold(1);
    autoCompleteTextView.setAdapter(adapter);
    autoCompleteTextView.addTextChangedListener(new StreetTextWatcher(
            autoCompleteTextView, adapter));

}
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <AutoCompleteTextView
        android:id="@+id/AndroidBooks"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:inputType="text">
    </AutoCompleteTextView>
</LinearLayout>

StreetArrayAdapter.java

public class StreetArrayAdapter extends ArrayAdapter<String> {

String TAG = getClass().getSimpleName();

public StreetArrayAdapter(Context context, int textViewResourceId) {
    super(context, textViewResourceId);
}

public void addAll(String[] streets) {
    for (String street : streets) {
        Log.v(TAG, "street = " + street);
        add(street);
    }
}

@Override
public void insert(String object, int index) {
    super.insert(object, index);
}

@Override
public void notifyDataSetChanged() {
    super.notifyDataSetChanged();
}

@Override
public void setDropDownViewResource(int resource) {
    super.setDropDownViewResource(resource);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    return super.getView(position, convertView, parent);

}


}

StreetTextWatcher.java

public class StreetTextWatcher implements TextWatcher {

private final StreetArrayAdapter adapter;
private boolean alreadyAdded = false;

String TAG = getClass().getSimpleName();
AutoCompleteTextView autoCompleteTextView;

public StreetTextWatcher(AutoCompleteTextView autoCTV,StreetArrayAdapter adapter) {
    this.adapter = adapter;
    autoCompleteTextView = autoCTV;
}

@Override
public void afterTextChanged(Editable s) {
    // not used
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
        int after) {
    if (s.length() < 1) {
        adapter.clear();

        alreadyAdded = false;
    }
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {

    Log.v(TAG, "char ---> = "+ s);
    if (s.length() == 1) {
        populateAdapter(s);

        alreadyAdded = true;
    }
}


private void populateAdapter(CharSequence s) {
    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("a")
            && !alreadyAdded) {
        Log.v(TAG, "inside A");
        adapter.addAll(StreetNames.STREETS_A);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("ä")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_A);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("b")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_B);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("c")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_C);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("d")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_D);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("e")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_E);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("f")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_F);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("g")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_G);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("h")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_H);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("i")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_I);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("j")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_J);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("k")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_K);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("l")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_L);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("m")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_M);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("n")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_N);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("o")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_O);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("ö")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_O);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("p")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_P);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("q")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_Q);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("r")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_R);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("s")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_S);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("t")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_T);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("u")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_U);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("ü")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_U);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("v")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_V);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("w")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_W);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("y")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_Y);
    }

    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("z")
            && !alreadyAdded) {
        adapter.addAll(StreetNames.STREETS_Z);
    }

    autoCompleteTextView.setAdapter(adapter);
}

}

StreetNames.java

public class StreetNames {
 public static String[] STREETS_A = {"Apple", "Ant", "ana","alia"};
 public static String[] STREETS_B = {"Ball", "Baby","banana","bear"};
 public static String[] STREETS_C = {"Cat", "Coffee", "cherry", "carrot"};
 public static String[] STREETS_D = {"Doll", "Dady", "dj", "don"};
 public static String[] STREETS_E = {"Elephant", "Eye", "earing", "easy"};
 /*
  .
  .
  */
 public static String[] STREETS_Z = {"Zebra", "Zero", "zzz", "zoya"};
}

如果您有任何疑问,请告诉我...


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