我的应用中有一个listView。对于listView中的每个元素,它都有一个Switch。以前我在listView Adapter的getView方法中为Switch实现了一个onClickListener。但是,我发现尽管用户点击交换机时它确实有效,但当用户在Switch上滑动时它不起作用。然后我尝试将onClickListener更改为onCheckedChangeListener。当用户在Switch上单击或滑动时它可以工作,但是,当我滚动listView以便元素消失时,我发现最初检查的Switch变为未选中状态。
你可以帮忙吗?下面是我在listView Adapter中的getView方法的代码:@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
class viewHolder {
public TextView tvSceneName;
public Switch swSelectSwitch;
}
final viewHolder holder;
final View v = convertView;
// Use ViewHolder to avoid findViewById each time the user scroll
if (convertView == null) {
holder = new viewHolder();
convertView = mInflater.inflate(R.layout.scene_list_element, parent, false);
holder.tvSceneName = (TextView) convertView.findViewById(R.id.tvSceneName);
holder.swSelectSwitch = (Switch) convertView.findViewById(R.id.swScene);
convertView.setTag(holder);
} else {
holder = (viewHolder) convertView.getTag();
}
if(holder.swSelectSwitch != null) {
// Set the switch to correct on/off status
holder.swSelectSwitch.setChecked(mDataSource.get(position).get_isOn());
// Set up On checked change listener for the switch
holder.swSelectSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {
// Set the new status to arraylist
Switch sw = (Switch) v.findViewById(R.id.swScene);
MainActivity.sceneArrayList.get(position).set_isOn(sw.isChecked());
});
}
}
修改 在进一步测试中,我发现我新添加的onCheckChangedListener中存在错误(因为我从onClickListener复制了一些代码)。另外我找到了一个解决方案,它是在我按代码设置Switch之前将onCheckChangedListener设置为null。
if(holder.swSelectSwitch != null) {
// Set the switch to correct on/off status
holder.swSelectSwitch.setOnCheckedChangeListener(null);
holder.swSelectSwitch.setChecked(mDataSource.get(position).get_isOn());
// Set up On checked change listener for the switch
holder.swSelectSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {
// Set the new status to arraylist
mDataSource.get(position).set_isOn(isChecked);
});
}
答案 0 :(得分:1)
ViewHolder
模式的要点是View
s正在被回收。
您从mDataSource
获取已检查状态,但未对其进行更新,因此当View
被回收时,Switch
将返回其原始(未选中)状态。< / p>
发生更改时,您应该更新mDataSource
中的状态:
@Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {
// Set the new status to arraylist
MainActivity.sceneArrayList.get(position).set_isOn(isChecked);
// updating mDataSource
mDataSource.get(position).set_isOn(isChecked);
}
答案 1 :(得分:0)
您应该删除第if(holder.swSelectSwitch != null) {
行:
滚动时,视图不会被销毁但会被回收,因此在滚动后调用getView
时,convertView
不为空。当convertView
不为空时,您将重新使用已创建的持有者并将其放入视图标记中。