AutoCompleteTextView和Spinner使用相同的适配器出现问题

4
我有一个“类别”列表,存储在我的应用程序中的ArrayAdapter中作为字符串。这很简单。该适配器是Activity的一个字段,并且可以在任何地方访问它。它在onCreate()期间填充值。
我有一个“条目”对话框,其中包含一个AutoCompleteTextView,它使用此适配器,并且非常好用。这基本上是一个添加新项目到列表的对话框。
我还有第二个对话框,它充当我的列表的过滤器,并具有单个Spinner,当创建对话框时,使用相同的ArrayAdapter。问题在于:
如果在输入对话框之前使用过滤器对话框,则Spinner将使用来自适配器的所有项目进行填充。运作良好。
每次我使用输入对话框时,AutoCompleteTextView都能正常工作。
问题出现在我使用输入对话框并在建议某些内容时选择AutoCompleteTextView中的项目后。即使我取消输入对话框,下一次打开筛选对话框时,Spinner最初显示从AutoCompleteTextView中最后选择的项目(而不是适配器中的第一个项目),并且仅在单击/触摸时显示该单个项目在Spinner的列表中。唯一的解决方法是结束应用程序并重新打开它。我没有在logcat中得到任何错误或有用的信息。
编辑-好吧,我删除了以前的代码,用我制作的简单测试用例替换它。最重要的是我想知道这是否是一个错误,还是预期结果。当在AutoCompleteTextView中选择建议时,我可以确认与其链接的ArrayAdapter已应用过滤,因此其计数受到影响,并且如果在Spinner中访问该适配器,则仅显示被过滤的项。我还添加了一个按钮来显示toast,以显示计数受到影响。在自动完成中键入“te”,然后选择Test entry之一。尝试旋转器或单击按钮以查看适配器的计数仅为2。
因此,最终问题是...除了在AutoCompleteTextView中键入和清除之外,是否可以重置适配器的过滤器?我找不到任何方法来做到这一点。在我的实际应用程序中,我通过设置临时适配器,复制主适配器的项目并将视图设置为使用临时适配器来解决了这个问题。我的手机运行2.2,并且我已经在模拟器中测试了高达2.3.3 API级别10。
main.xml的xml。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
<AutoCompleteTextView android:id="@+id/actv"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true" />
<Spinner android:id="@+id/spinner"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:layout_centerInParent="true" />
<Button android:id="@+id/button"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:text="Check It"
    android:layout_alignParentBottom="true"
    android:layout_centerInParent="true" />
</RelativeLayout>

MainActivity.java的代码如下:

public class MainActivity extends Activity {
    /** Called when the activity is first created. */

    AutoCompleteTextView actv;
    Spinner spinner;
    Button button;

    String [] adapterList = {"Test1", "Test2", "Garbage1", "Garbage2"};

    ArrayAdapter<String> adapter;

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

        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, adapterList);

        actv = (AutoCompleteTextView) findViewById(R.id.actv);
        spinner = (Spinner) findViewById(R.id.spinner);
        button = (Button) findViewById(R.id.button);

        actv.setAdapter(adapter);
        spinner.setAdapter(adapter);

        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "" + adapter.getCount() + " Items in Adapter", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

发布代码,特别是创建对话框的部分。 - dmon
我已经编辑了几次帖子。现在的帖子包括一个简单易复制的测试用例。 - Maximus
1个回答

2
查看AutoCompleteTextView源代码,它确实过滤了ArrayAdapter:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/widget/AutoCompleteTextView.java#AutoCompleteTextView.performFiltering%28java.lang.CharSequence%2Cint%29

您可能想要在Spinner的onClick回调函数中删除筛选器:
Filter filter = adapter.getFilter();
filter = null;

(请看AutoCompleteTextView中的setAdapter方法,大约在第600行附近)

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/widget/ArrayAdapter.java#ArrayAdapter.getFilter%28%29

如果它起作用,请告诉我

顺便问一下,适配器是否会动态更改?你使用两个适配器的“解决方法”可能比搞弄过滤器要好。如果用户开始输入一个单词,然后点击旋转器,取消并返回到单词,现在自动完成将没有意义,除非你保存过滤器并以某种方式恢复它。
我确实认为两个基于相同字符串数组的适配器是更好的解决方案。


我可能会坚持我的解决方法。在我的实际应用中,自动完成视图和微调器位于不同的对话框中,因此它们永远不会同时显示在屏幕上。这正是我要找的答案,非常感谢。23小时后你将获得赏金...如果你有时间并且擅长布局,请看一下我的最新问题。 - Maximus
@Maximus 我会在家里试一试(我这里没有 SDK)。我在“相关”栏目中找到了这个问题:https://dev59.com/0lXTa4cB1Zd3GeqP48Ua(不同的问题,但类似的问题)。 - Aleadam
@Maximus 顺便说一下,你有一整个星期的时间来获得悬赏。如果你愿意,你可以等待看看是否有其他人提出更好的解决方案。 - Aleadam
我在布局帖子上得到了答案,但我仍然需要更多关于它的解释。至于赏金,这确实是我需要知道的,所以我怀疑还有更多的见解可以被获取。 - Maximus

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