Android 在自定义列表视图中向下滚动会使项目';s微调器为空
我有一个带有自定义ArrayAdapter和自定义项的ListView。这些项目包含多个视图元素,包括微调器。此微调器的阵列适配器设置如下:Android 在自定义列表视图中向下滚动会使项目';s微调器为空,android,android-listview,android-arrayadapter,android-spinner,Android,Android Listview,Android Arrayadapter,Android Spinner,我有一个带有自定义ArrayAdapter和自定义项的ListView。这些项目包含多个视图元素,包括微调器。此微调器的阵列适配器设置如下: // Method to set or update the Tags in the Spinner public void updateTagsSpinner(MyHolder h, Spinner sp){ if(h != null && h.orderedProductItem != null){ // If
// Method to set or update the Tags in the Spinner
public void updateTagsSpinner(MyHolder h, Spinner sp){
if(h != null && h.orderedProductItem != null){
// If the given Spinner null, it means we change the OrderedProductItem's Spinner
// Is the given Spinner not null, it means we change the Manage Tag's PopupWindow's Spinner
if(sp == null)
sp = h.spTags;
// We know it's an ArrayAdapter<String> so we just ignore the
// "Unchecked cast from SpinnerAdapter to ArrayAdapter<String>" warning
@SuppressWarnings("unchecked")
ArrayAdapter<String> spAdapt = (ArrayAdapter<String>) sp.getAdapter();
ArrayList<String> tagStrings = Controller.getInstance().getAllTagsWithOrderedProductItem(h.orderedProductItem));
if(tagStrings != null && tagStrings.size() > 0){
if(spAdapt == null){
spAdapt = new ArrayAdapter<String>(ChecklistActivity.this, android.R.layout.simple_spinner_item, tagStrings);
spAdapt.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// ArrayAdapter's setNotifyOnChange is true by default,
// but I set it nonetheless, just in case
spAdapt.setNotifyOnChange(true);
sp.setAdapter(spAdapt);
}
else{
spAdapt.clear();
spAdapt.addAll(tagStrings);
}
}
sp.setSelection(h.orderedProductItem.getSelectedFilter());
}
}
//在微调器中设置或更新标记的方法
公共无效更新TagSpinner(MyHolder h,Spinner sp){
如果(h!=null&&h.orderedProductItem!=null){
//如果给定的微调器为null,则表示我们更改OrderedProductItem的微调器
//如果给定的微调器不为null,则表示我们更改了Manage标记的PopupWindow的微调器
如果(sp==null)
sp=h.spTags;
//我们知道这是ArrayAdapter,所以我们忽略了
//“未选中从SpinnerAdapter到ArrayAdapter的强制转换”警告
@抑制警告(“未选中”)
ArrayAdapter spAdapt=(ArrayAdapter)sp.getAdapter();
ArrayList TagString=Controller.getInstance().getAllTagsWithOrderedProductItem(h.orderedProductItem));
if(tagStrings!=null&&tagStrings.size()>0){
如果(spAdapt==null){
spAdapt=new ArrayAdapter(ChecklistActivity.this、android.R.layout.simple\u微调器\u项、标记字符串);
spAdapt.setDropDownViewResource(android.R.layout.simple\u微调器\u下拉菜单\u项);
//ArrayAdapter的setNotifyOnChange默认为true,
//但我还是设定了,以防万一
spAdapt.setNotifyOnChange(true);
sp.setAdapter(spAdapt);
}
否则{
spAdapt.clear();
spAdapt.addAll(标记字符串);
}
}
sp.setSelection(h.orderedProductItem.getSelectedFilter());
}
}
由于某种原因,每次我向下滚动然后再向上滚动时,我的微调器都是空的。。当我点击它们时,我甚至不能再打开任何微调器(包括那些不是空的微调器),因为有一个警告:
W/InputEventReceiver(899):试图完成输入事件,但输入事件接收器已被释放
好的,我发现了问题,这是一个令人讨厌的问题。。这就是我将问题/答案作为一个整体发布以帮助其他有类似问题的人的原因 警告:adapter.clear()更改ArrayAdapter使用的原始列表强> 在我的控制器中,我有一个HashMap(
allTagsOfProducts
),带有key=int-productId
和value=ArrayList-productTags
。在getAllTagsWithOrderedProductItem方法中,我使用以下内容:
public ArrayList<String> getAllTagsWithOrderedProductItem(OrderedProductItem opi){
if(opi != null && opi.getProductId() > 0){
// Check if a new Tag has been added / removed
if(getProductById(opi.getProductId()).getTagsHasChanged()){
ArrayList<String> newProductTags = new ArrayList<String>();
... // Do some stuff to fill the newProductTags-List
// Replace the previously saved Tags of this Products with this updated one
allTagsOfProduct.put(opi.getProductId(), newProductTags);
// Set the boolean on false
getProductById(opi.getProductId()).setTagsHasChanged(false);
// And return this update list
return newProductTags;
}
// If nothing is added / removed, just return the list we already saved
else
return allTagsOfProduct.get(opi.getProductId());
}
// If the given OrderedProductItem is null return an empty list
else
return new ArrayList<String>();
}
PS:我也无法再打开非空微调器,它给了我警告的原因是因为自定义ArrayAdapter(在本例中是我的ListView)的getView()循环原则。它将该项目的微调器重新用于另一个项目。因此,即使这个新项目的微调器正确地填充了另一个项目的ArrayList/ArrayAdapter,输入EventHandler也不会重置,因此我仍然会收到回收ListView项目中非空微调器的此警告
// We create a new ArrayList here, since spAdapt.clear() changes the original list
// all the way into the Controller's HashMap.. You gotta love the Java references.. >.>
ArrayList<String> tagStrings = new ArrayList<String>(
Controller.getInstance().getAllTagsWithOrderedProductItem(h.orderedProductItem));