我有一个带有自定义适配器的ListView,每行包含一个用户可以设置的搜索栏。每个搜索栏都有一个在适配器中设置的seekBarChangeListener,当用户更改ListView中搜索栏的值时,适配器的arraylist会更新。这就是我在适配器getView()
中得到的内容:
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
final ViewHolder viewHolder;
View v = convertView;
if(v == null){
v = inflater.inflate(R.layout.row, null);
viewHolder = new ViewHolder();
viewHolder.contentView = (TextView) v.findViewById(R.id.pref_content);
viewHolder.sliderView = (SeekBar) v.findViewById(R.id.pref_slider);
v.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) v.getTag();
}
// Get initial values
Prompt p = promptList.get(position);
String content = p.getContent();
int sliderLevel = p.sliderLevel();
// Set views with initial values
viewHolder.contentView.setText(content);
viewHolder.sliderView.setMax(noOfLevels);
viewHolder.sliderView.setProgress(sliderLevel);
// Set Change Listener for Seekbar
viewHolder.sliderView.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// Set new level of the Slider in the Array List
promptList.get(position).setSliderLevel(progress);
}
});
return v;
}
因此,当用户更改搜索条的值时,ChangeListener将从ArrayList获取对象并设置其新的sliderLevel值。但是,如果我在ListView中设置一个新值然后再向上滚动,那么再次调用getView,即使我更改了arrayList中的值,搜索栏也会返回其初始值。
有人可以帮我看看我在哪里出错吗?感谢
答案 0 :(得分:1)
每次用户更改onProgressChanged()
值时,都会调用方法SeekBar
。但它也将被称为“by system”(我认为这是因为SeekBar
作为convertView的一部分被回收)。这就是为什么有必要检查fromUser
是否为真:
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (!fromUser) return;
// Set new level of the Slider in the Array List
promptList.get(position).setSliderLevel(progress);
}
在您的情况下,您不必致电notifyDatasetChanged()
,因为只要仍然显示一个特定的SeekBar
,只有用户才会更改其进度。一旦隐藏(因为用户滚动)并且此位置的数据必须稍后再次显示,将调用getView()
并将正确的值设置为convertView中的SeekBar
然后显示你的数据。
另一个想法(性能原因):考虑只在用户停止操作滑块时才更改promptList.get(position)
的进度值。为此,您可以覆盖onStopTrackingTouch()
而不是onProgressChanged()
并写入
promptList.get(position).setSliderLevel(seekBar.getProgress());
答案 1 :(得分:0)
所以我设法通过将promptList.get(position).setSliderLevel(progress)
从onProgressChanged()
移到搜索栏的onStopTrackingTouch()
中的OnSeekBarChangeListener()
来解决问题,并且还从{更改ListView的高度{1}}到wrap_content
。这两件事都导致了不良行为。
出于某种原因onProgressChanged()在运行时被调用,根本没有触及搜索条,即使在使用arrayList中的值初始化搜索条后设置了changeListener。
编辑:0X0nosugar的答案解释了这种行为