我有一个ListFragment
,其中包含TextView
和每个项目中的两个按钮。单击一个Button
可更改列表项的背景颜色,单击另一个将从列表中删除该项。现在,只要不进行滚动,就会保持项目的背景状态。一旦列表变得足够长以滚动,各种项目的背景状态/视图将被回收,从而导致未被点击的列表项目的背景颜色发生变化。
我可以通过存储可访问的列表项位置来保留后台状态
getView(int position, View convertView, ViewGroup parent)
中的ListFragment CustomAdapter
(我的案例中为SimpleAdapter
)的ArrayList
方法,然后检查ArrayList
是否包含所选位置就在返回膨胀的视图之前。如果该位置存在于ArrayList
中,则该项目的背景颜色设置为绿色,否则将其设置为透明。这是我的代码:
@Override
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
final int pos = position;
view = super.getView(position,convertView,parent);
Button buttonChangeBackground = (Button) view.findViewById(R.id.button_1);
buttonChangeBackground.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
View view =(View) v.getParent();
view.setBackgroundColor(Color.GREEN);
// storing list item positions in ArrayList
coloredItems.add(pos);
}
});
Button buttonDelete = (Button) view.findViewById(R.id.button_2);
buttonDelete.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
datalist.remove(pos);
notifyDataSetChanged();
}
});
/*
* Using the stored positions to retain background state.
*/
if(coloredItems.contains(pos))
view.setBackgroundColor(Color.GREEN);
else
view.setBackgroundColor(Color.TRANSPARENT);
return view;
}
只要没有从列表中删除任何项目,这就有效。我理解,一旦列表项被删除,删除项之后的所有项都需要在ArrayList
中将其位置减1,以便状态保持在其修改的位置。我尝试了很多方法但总是抛出IndexOutOfBoundsException.
我应添加哪些代码以确保即使删除列表项后所有列表项都保留其背景状态?这似乎是一个简单的ArrayList
操作问题
但是我无法找到解决方案。
答案 0 :(得分:1)
回答我的问题。这个答案是基于@pskink留下的评论。
在为适配器创建数据集时,添加一个额外的键,指示列表项的默认背景状态和适当的值。在我的情况下,我使用
map.add("BACKGROUND","BACKGROUND_PLAIN");
现在,在getView方法中,更改Button的OnClickListener中用于更改View背景的键的值。就我而言:
Button buttonChangeBackground = (Button) view.findViewById(R.id.button_1);
buttonChangeBackground.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// obtaining map associated with current data item's position.
final HashMap<String,String> map = datalist.get(pos);
// changing value associated with key.
map.put("BACKGROUND", "GREEN");
notifyDataSetChanged();
}
});
现在,就在getView方法返回之前,检查与当前视图关联的数据项是否包含修改后的值或为背景设置的默认值。如果修改了该值,请将视图背景设置为绿色,否则将背景设置为其默认值,在我的情况下为Color.Transparent。
hashMap = datalist.get(position);
if(hashMap.containsValue("GREEN")){
view.setBackgroundColor(Color.GREEN);
}
else{
view.setBackgroundColor(Color.TRANSPARENT);
}
完整代码:
@Override
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
final int pos = position;
HashMap<String,String> hashMap = new HashMap<String,String>();
view = super.getView(position,convertView,parent);
Button buttonChangeBackground = (Button) view.findViewById(R.id.button_1);
buttonChangeBackground.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// obtaining map associated with current data item's position.
final HashMap<String,String> map = datalist.get(pos);
// changing value associated with key.
map.put("BACKGROUND", "GREEN");
notifyDataSetChanged();
}
});
Button buttonDelete = (Button) view.findViewById(R.id.button_2);
buttonDelete.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
datalist.remove(pos);
notifyDataSetChanged();
}
});
hashMap = datalist.get(position);
if(hashMap.containsValue("GREEN")){
view.setBackgroundColor(Color.GREEN);
}
else{
view.setBackgroundColor(Color.TRANSPARENT);
}
return view;
}
答案 1 :(得分:0)
使用选择器为你在LsitView
中扩充的布局,设置2个选择器,并在编译时在xml中设置其中一个选项,另一个将在运行时按下按钮时动态设置
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:state_focused="true"
android:drawable="@drawable/my_item_disabled" />
<item android:state_pressed="true"
android:drawable="@drawable/my_item_pressed" />
<item android:state_focused="true"
android:drawable="@drawable/my_item_focused" />
</selector>