虽然在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) {
}
});
答案 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();