Android - 基于微调器选择更新列表视图并不起作用

时间:2017-09-08 19:27:26

标签: android listview spinner adapter android-adapter

虽然在stackoverflow上有很多关于这个主题的问题,但我可以说我已经浏览了很多问题并尝试了不同的东西,但我仍然无法让它工作。

我有一个ListView,我使用我自己创建的自定义类的自定义适配器填充。我也有一个微调器,我试图用作列表的过滤器。

这是我的简化代码,我删除了与此相关的所有内容,使其尽可能清晰,同时简化了一些变量名称:

public class OnlineNavActivity extends AppCompatActivity {

    private ListView tourList;
    private ArrayList<Tour> toursData;
    private Spinner filterSpinner;
    private TourAdapter tourAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tours_online);

        // Set up the spinner
        filterSpinner = (Spinner) findViewById(R.id.country_spinner);
        addItemsToSpinner();
        filterSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String selectedCountry = (String) parent.getItemAtPosition(position);
                Log.i(LOG_TAG, selectedCountry);
                if (!selectedCountry.equals(Data.ALL_COUNTRIES)) {  // if string does not equal to "All Countries"
                    toursData = Data.listByFilter(selectedCountry);
                }
                else {
                    toursData = Data.dataList;
                }
                tourAdapter = new TourAdapter(getApplicationContext(), toursData);
                tourAdapter.notifyDataSetChanged();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                toursData = Data.dataList;
                tourAdapter = new TourAdapter(getApplicationContext(), toursData);
                tourAdapter.notifyDataSetChanged();
            }
        });

        // Assign all of the data to the array at first, will change by filter spinner
        toursData = Data.dataList;

        // Generate the list view
        tourList = (ListView) findViewById(R.id.online_nav_list);
        tourAdapter = new TourAdapter(this ,toursData);
        tourList.setAdapter(tourAdapter);


    }

Data.listByFilter()是我在另一个类中创建的方法,该类返回带有应用过滤器的ArrayList。

问题是,当我点击微调器并选择一个项目时 - 没有任何事情发生。

我尝试使用tourAdapter.clear(),然后使用add命令添加项目,但这些项目不起作用(对于微调器中的任何选择,ListView变为空)。

向适配器添加项目时,项目已添加到ListView并在那里更新,但这不是我需要的,只是在我试图解决这个问题时有用的东西。

感谢。

修改

经过多次尝试,我终于找到了解决方案。虽然它看起来不是一个最佳解决方案,但由于我在每个微调器动作上声明了一个新的TourAdapter,这是唯一对我有效的方法。 我做了什么,宣布一个新的TourAdapter然后调用setAdapter。 另外,我已将onNothingSelected作为空方法。这就是它的样子(所有其他代码保持不变):

filterSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String selectedCountry = (String) parent.getItemAtPosition(position);
                Log.i(LOG_TAG, selectedCountry);
                if (!selectedCountry.equals(Data.ALL_COUNTRIES)) {  // if string does not equal to "All Countries"
                    toursData = Data.listByFilter(selectedCountry);
                    Log.i(LOG_TAG, "first country is" + toursData.get(0).getCountry());
                }
                else {
                    toursData = Data.dataList;
                }
                tourAdapter = new TourAdapter(getApplicationContext() ,toursData);
                tourList.setAdapter(tourAdapter);
                //tourAdapter.notifyDataSetChanged();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

1 个答案:

答案 0 :(得分:1)

问题是,每次单击Spinner并且此适配器未链接到列表时,您正在创建新的适配器(onItemSelected和onNothingSelected方法中的新TourAdapter(...))。

在这两种方法中,您应该获取列表已经具有的适配器(使用tourList.setAdapter设置它),而不是创建新的方法,在适配器上创建一个方法,在其上设置新元素并更新列表与notifyDataSetChange。

String selectedCountry = (String) parent.getItemAtPosition(position);
Log.i(LOG_TAG, selectedCountry);
if (!selectedCountry.equals(Data.ALL_COUNTRIES)) {
    toursData = Data.listByFilter(selectedCountry);
} else {
    toursData = Data.dataList;
}
tourAdapter = ((TourAdapter) tourList.getAdapter()).setNewElements(toursData);
tourAdapter.notifyDataSetChanged();

setNewElements应该是适配器中的一个方法,如下所示:

public void setNewElements(List<Tour> newElementsList) {
    this.myElements = newElementsList;
}

*****编辑*****

String selectedCountry = (String) parent.getItemAtPosition(position);
Log.i(LOG_TAG, selectedCountry);
toursData.clear();
if (!selectedCountry.equals(Data.ALL_COUNTRIES)) {
    toursData.addAll(Data.listByFilter(selectedCountry));
}
else {
    toursData.addAll(Data.dataList);
}
tourAdapter.notifyDataSetChanged();